所有
在办公室度过了艰难的一天...我正在尝试在当地时间锻炼一天的开始,即午夜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
答案 0 :(得分:0)
听起来你只想将所有时间部分设置为零。您可以使用:
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
(假设您已正确设置日历中的时区。)
请注意,这不是必然有效 - 在某些时区(例如巴西),在夏令时过渡午夜要么出现两次,要么根本不出现。
就个人而言,我会开始发布关于转移到Joda Time的声音,这使得所有这一切变得更加简单:)
答案 1 :(得分: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 );
}
希望这有帮助。
答案 2 :(得分:0)
您正在使用过时的课程。在Java 8及更高版本中,使用内置的java.time框架。
不要假设当天00:00:00.0
开始。由于夏令时(DST)等异常情况,每天的开始时间可能因时区而异。让java.time类通过调用LocalDate::atStartOfDay
确定正确的时间。
避免使用3-4个字母区域缩写,例如BST
,EST
等。它们既不标准也不独特。使用proper time zone names。
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)和某些时区的其他异常,第一时刻不总是00:00:00
。这就是我们依赖atStartOfDay
方法而不是硬编码零时间的原因。