Java Date (Calendar) calculating the start of a day in local time given a date time
All,
Having a hard day in the office with this one... I am trying to workout the start of a day in Local Time, i.e. Midnight 00:00:00, given any calendar date.
Given the following days, I want to calculate the start of the day at local time midnight:
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
At present, I am parsing the String Time 开发者_运维问答into a GregorianCalendar using a SimpleDateFormat. This gives me the GMT/UTC time to calculate from.
So I have some code which parses the string into a 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;
}
Now I need to set it to midnight locally:
public void setToStartOfDayLocally(GregorianCalendar cal) {
????
}
I am not too sure what I need to do at the minute with the Calendar. Unfortunately we are not moving to JODA date in the near future. I am also not accounting for different time zones with my example.
Any thoughts?
Thanks,
Andez
I think this code might solve your issue. I am using it to convert from time in local timezone to another.
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 );
}
Hope this helps.
It sounds like you just want to set all of the time parts to zero. You can use:
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
(Assuming you've got the time zone in the calendar set properly.)
Note that that isn't necessarily valid though - in some time zones (e.g. Brazil), at a daylight saving transition midnight either occurs twice or not at all.
Personally I'd start making noises about moving to Joda Time though, which makes all of this a lot simpler :)
java.time
You are using outmoded classes. In Java 8 and later, use built-in java.time framework.
Do not assume the day starts at the time 00:00:00.0
. Because of anomalies such as Daylight Saving Time (DST) the start-of-day may vary by time zone. Let the java.time classes determine the correct time with a call to LocalDate::atStartOfDay
.
Avoid using 3-4 letter zone abbreviations such as BST
, EST
, and so on. They are neither standardized nor unique. Use proper time zone names.
An Instant
is a moment on the timeline in UTC. Apply a time zone to get a ZonedDateTime
. Extract a date-only value from that date-time, a LocalDate
. Apply a time zone with a call to atStartOfDay
to get back to a ZonedDateTime
set to the first moment of the day in that time zone.
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 );
Tip: Avoid the word “midnight”. Does not have a precise definition. Some people think of trying to determine the last moment of the day which is a problem because of an infinitely divisible fraction of a second. Some people think of the the special string “24:00” to indicate the stroke of midnight which further confuses date-time handling. Experience from the Joda-Time project teaches us that it is best to focus on “first moment of the day” as a clear and precise meaning. Also, be aware that the first moment is not always 00:00:00
, due to Daylight Saving Time (DST) and other anomalies in some time zones. That is why we depend on the atStartOfDay
method rather than hard-code a zero-time-of-day.
精彩评论