Java Date (Calendar) calculating the start of a da

2019-06-04 02:43发布

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

3条回答
欢心
2楼-- · 2019-06-04 03:00

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.

查看更多
来,给爷笑一个
3楼-- · 2019-06-04 03:00

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 :)

查看更多
SAY GOODBYE
4楼-- · 2019-06-04 03:07

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.

查看更多
登录 后发表回答