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将String Time解析为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
我认为这段代码可能会解决您的问题。 我用它来从当地时区的时间转换到另一个时区。
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 ); }
希望这可以帮助。
听起来你只想将所有时间部分设置为零。 您可以使用:
cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0);
(假设您已正确设置日历中的时区。)
请注意,这不一定有效 – 在某些时区(例如巴西),在夏令时过渡午夜要么发生两次,要么根本不发生。
就个人而言,我会开始制作关于转移到Joda Time的声音,这使得所有这一切变得更加简单:)
java.time
您正在使用过时的课程。 在Java 8及更高版本中,使用内置的java.time框架。
不要假设这一天从00:00:00.0
。 由于夏令时(DST)等exception情况,每天的开始时间可能因时区而异。 让java.time类通过调用LocalDate::atStartOfDay
来确定正确的时间。
避免使用3-4字母区域缩写,如BST
, EST
等。 它们既不标准也不独特。 使用适当的时区名称 。
Instant
是UTC时间轴上的一个时刻。 应用时区以获取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)和某些时区的其他exception,第一时刻并非总是00:00:00
。 这就是为什么我们依赖atStartOfDay
方法而不是硬编码零时间。