2011-09-28 126 views
1

所有本地时间开始,Java的日期(日历)计算,每天在给定的日期时间

有一个艰难的一天在这一个办公室......我想锻炼一天的开始在当地时间,即午夜00:00:00,以任何日历日期为准。

考虑接下来的日子里,我想在当地时间午夜来计算一天的开始:

 Time      Start Day (Local)   Start Day (GMT) 
2011-03-27 00:00:00 GMT -->  2011-03-27 00:00:00 GMT --> 2011-03-27 00:00:00 GMT 
2011-03-27 01:00:00 GMT -->  2011-03-27 00:00:00 GMT --> 2011-03-27 00:00:00 GMT 
2011-03-27 02:00:00 GMT -->  2011-03-27 00:00:00 GMT --> 2011-03-27 00:00:00 GMT 
2011-04-01 00:00:00 BST -->  2011-04-01 00:00:00 BST --> 2011-03-31 23:00:00 GMT 
2011-10-30 00:00:00 BST -->  2011-10-30 00:00:00 BST --> 2011-10-29 23:00:00 GMT 
2011-10-30 01:00:00 BST -->  2011-10-30 00:00:00 BST --> 2011-10-29 23:00:00 GMT 
2011-10-30 01:00:00 GMT -->  2011-10-30 00:00:00 BST --> 2011-10-29 23:00:00 GMT 
2011-11-01 00:00:00 GMT -->  2011-11-01 00:00:00 GMT --> 2011-11-01 00:00:00 GMT 

目前,我使用的是SimpleDateFormat的解析字符串时间到一个GregorianCalendar。这给我的GMT/UTC时间来计算。

所以我有一些代码解析字符串转换成一个GregorianCalendar:

public GregorianCalendar getCalendar(String dateTime) { 
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    GregorianCalendar cal = new GregorianCalendar(); 
    cal.setTime(sdf.parse(dateTime, new ParsePosition(0))); 

    return cal; 
} 

现在我需要在本地设置为午夜:

public void setToStartOfDayLocally(GregorianCalendar cal) { 
    ???? 
} 

我也不太清楚我需要什么在日历上随时做。不幸的是,我们不会在不久的将来转向JODA的日期。我也没有用我的例子来解释不同的时区。

有什么想法?

感谢,

Andez

回答

0

我觉得这个代码可以解决您的问题的声音。我正在使用它将本地时区的时间转换为另一个时区。

public static Date convertLocalDateToDateTimezone(Date localDate, String timezone) { 
    TimeZone localTimeZone = TimeZone.getDefault(); 
    TimeZone timezone = TimeZone.getTimeZone(timezone); 
    long gmtMillis = localDate.getTime(); 
    long result = gmtMillis + timezone.getOffset(gmtMillis) - localTimeZone.getOffset( gmtMillis); 
    return new Date(result); 
} 

希望这会有所帮助。

0

这听起来像你只是想所有的时间部分设置为零。您可以使用:

cal.set(Calendar.HOUR_OF_DAY, 0); 
cal.set(Calendar.MINUTE, 0); 
cal.set(Calendar.SECOND, 0); 
cal.set(Calendar.MILLISECOND, 0); 

(假设你有日历的时区设置正确。)

请注意,这不是一定有效,但 - 在某些时间段(如巴西),在午夜的夏令时转换发生两次或根本不发生。

个人而言,我会开始做关于搬迁到约达时间虽然,这使得这一切变得简单许多:)

0

java.time

您正在使用过时的类。在Java 8及更高版本中,使用内置的java.time框架。

不要假设当天开始的时间是00:00:00.0。由于夏令时(DST)等异常情况,开始日期可能因时区而异。让java.time类通过调用LocalDate::atStartOfDay来确定正确的时间。

避免使用3-4字母区域缩写,如BST,EST等。它们既不标准也不唯一。使用proper time zone names

InstantUTC中时间轴上的一个时刻。应用时区获得ZonedDateTime。从该日期时间提取仅包含日期的值,即LocalDate。通过拨打atStartOfDay来申请一个时区,以回到设置为该时区一天中的第一个时刻的ZonedDateTime

Instant now = Instant.now(); 
ZoneId zoneId = ZoneId.of("America/Montreal"); 
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant , zoneId); 
LocalDate localDate = zdt.toLocalDate(); 
ZonedDateTime zdtStart = localDate.atStartOfDay(zoneId); 

提示:避免单词“午夜”。没有一个确切的定义。有些人认为试图确定一天中的最后一刻,这是一个无法分割的一秒的问题。有些人想到了特殊的字符串“24:00”来表示午夜的中风,这进一步混淆了日期处理。 Joda-Time项目的经验告诉我们,最好把重点放在“一天中的第一时刻”上,作为一个清晰明确的含义。此外,请注意,由于夏令时(DST)和其他时区中的其他异常情况,第一时间是而非始终为00:00:00。这就是为什么我们依赖于atStartOfDay方法而不是硬编码零时间的方法。