1

如何获取格式中两个字符串的持续时间YYYYMMDDTHHMMSS

我正在尝试使用 Calendar 类并检查getTimeInMillis(). 我遇到的问题是它不一致。知道我做错了什么吗?每次我运行这个程序时,我都会得到 40-70 行输出到控制台,而它应该没有。

public class DurationTester {

    /**
     * Get the duration between two given times
     * @param time1 yyyymmddThhmmss
     * @param time2 yyyymmddThhmmss
     * @return minutes between time1 and time2
     */
    public static int getDuration(String time1, String time2){
        int yyyy1 = Integer.parseInt(time1.substring(0,4));
        int mm1 = Integer.parseInt(time1.substring(4,6));
        int dd1 = Integer.parseInt(time1.substring(6,8));
        int hh1 = Integer.parseInt(time1.substring(9,11));
        int min1 = Integer.parseInt(time1.substring(11,13));

        int yyyy2 = Integer.parseInt(time2.substring(0,4));
        int mm2 = Integer.parseInt(time2.substring(4,6));
        int dd2 = Integer.parseInt(time2.substring(6,8));
        int hh2 = Integer.parseInt(time2.substring(9,11));
        int min2 = Integer.parseInt(time2.substring(11,13));

        Calendar cal1 = Calendar.getInstance();
        cal1.set(yyyy1, mm1, dd1, hh1, min1, 0);
        Calendar cal2 = Calendar.getInstance();
        cal2.set(yyyy2, mm2, dd2, hh2, min2, 0);
        long milliSec = cal1.getTimeInMillis()-cal2.getTimeInMillis();
        long nonNegativeMS = Math.abs(milliSec);
        long seconds = nonNegativeMS / 1000;
        long minutes = seconds / 60;        
        return (int)minutes;
    }

    public static void main(String[] args){
        String t1 = "20130108T150000";
        String t2 = "20130108T131500";

        int errors = 0;
        for(int i=0; i<5000; i++){
            int duration = getDuration(t1,t2);
            if(duration == 104){
                System.out.println("ERROR: Should only be 105 ("+errors++ +")");
            }
        }
    }
}
4

5 回答 5

2

您可以使用 SimpleDateFormat API 解析您的 String :

public static void main(String[] args) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
    try {
        Date date1 = sdf.parse("20130108T150000");
        Date date2 = sdf.parse("20130108T131500");
        System.out.println((date1.getTime() - date2.getTime())/1000/60);
    } catch (ParseException e) {
       e.printStackTrace();
    }
}
于 2013-08-08T07:12:48.767 回答
2

这是一个记录在案的错误

尝试在设置之前清除日历:

cal1.clear();
cal1.set(yyyy1, mm1, dd1, hh1, min1, 0);

cal2.clear();
cal2.set(yyyy2, mm2, dd2, hh2, min2, 0);
于 2013-08-08T07:23:57.027 回答
1

尝试这个

    String t1 = "20130108T150000";
    String t2 = "20130108T131500";
    DateFormat df=new SimpleDateFormat("yyyyMMdd'T'HHmmss");
    Date date1=df.parse(t1);
    Date date2=df.parse(t2);

    System.out.println(date2.getTime()-date1.getTime());  // time difference in mil-seconds
于 2013-08-08T07:01:12.830 回答
1

我会建议使用SimpleDateFormat解析你String的日期对象

SimpleDateFormat date_format = new SimpleDateFormat("yyyyMMdd'T'HHmmSS");
Date dateParsed = date_format.parse(yourStringDate)

您可以使用该Date.getTime()函数以毫秒为单位获取等效的日期对象并执行两个日期对象之间的差异

于 2013-08-08T07:02:44.357 回答
1

首先,您的日期转换关闭Calendar月份索引为零(Janurary实际上是月份),因此您的日期实际上被转换为,0而不是 begin ,这本身不是问题的根源,而是关注。Tue Jan 08 15:00:00 EST 2013Fri Feb 08 15:00:00 EST 2013

相反,您应该使用...

public static final SimpleDateFormat SDF = new SimpleDateFormat("yyyyMMdd'T'HHmmss");

public static int getDuration(String time1, String time2){
    Date date1 = SDF.parse(time1);
    Date date2 = SDF.parse(time2);

    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(date1);
    Calendar cal2 = Calendar.getInstance();
    cal2.setTime(date2);

String值转换回Date

现在,对于你的问题的原因......

因为您正在Calendar使用 设置值set(int year, int month, int date, int hourOfDay, int minute, int second),日历实例仍然包含它创建时的毫秒数(Calendar.getInstance()将返回一个Calendar集合到它创建的日期/时间),但您不会将这些值归零。

这会导致您的计算出现错误

你不应该依赖CalendarDate计算持续时间,它们在很长一段时间内是不可靠的,相反你应该使用JodaTime

DateTime dt1 = new DateTime(date1);
DateTime dt2 = new DateTime(date2);

Duration duration = new Duration(dt2, dt1);
System.out.println(duration.getStandardDays());
System.out.println(duration.getStandardHours());
System.out.println(duration.getStandardMinutes());
于 2013-08-08T07:26:01.080 回答