-1

I am trying to get the start time (00:00:00) and the end time (23:59:59) of a day in the PST time zone. I have tried the following code, but for some reason, I am only getting the start and end times in UTC. I have tried changing the timezone to include "America/Los_angeles", but the output timestamp is always showing start and end times for GMT/UTC.

My code:

val time_zone = ZoneId.of("America/Los_Angeles")
val today_date = LocalDate.now(time_zone).plusDays(0)
val start_time = today_date + " " + "00:00:00"
val end_time = today_date + " " + "23:59:59"

val date_format = new SimpleDateFormat("yyyy-MM-dd");
val start_millis = date_format.parse(start_time).getTime();
val end_millis = date_format.parse(end_time).getTime();

start_millis

Output:

res375: Long = 1656460799000

In the epoch converter, 1656460799000 gives me this: The start time is 00:00 in UTC, not in America/Los_Angeles time

Anything I am missing here? Should I update any package, etc.?

  • I believe the question has been already answered here https://stackoverflow.com/a/35187046/17949945 – Alexander Ivanchenko Jun 28 '22 at 22:13
  • Does this answer your question? [How can I create a Java 8 LocalDate from a long Epoch time in Milliseconds?](https://stackoverflow.com/questions/35183146/how-can-i-create-a-java-8-localdate-from-a-long-epoch-time-in-milliseconds) – Alexander Ivanchenko Jun 28 '22 at 22:14
  • tried that, didnt work well. I tried SystemDefault, it still didnt work. Also, the solutions for Instant.() seem to work only for the current time, not which ever time I want. – Illustrious Imp Jun 28 '22 at 22:21
  • 1
    *Instant.() seem to work only for the current time* - that's incorrect check this code https://www.jdoodle.com/ia/sI3 it'll bring you back to 1970. It **does** work with any amount of milliseconds you provide. – Alexander Ivanchenko Jun 28 '22 at 22:34
  • @AlexanderIvanchenko Those are not quite duplicates. Those questions are about a moment. This question is about a pair of moments, tracking the beginning and end of a full day. This Question here is *very* likely a duplicate, but I did not find original. Hence my Answer. – Basil Bourque Jun 29 '22 at 20:44
  • 1
    @BasilBourque OK, retracting the close vote. – Alexander Ivanchenko Jun 30 '22 at 11:36

2 Answers2

4

java.time

The modern approach uses the java.time classes only.

No need to ever use SimpleDateFormat, Date, Calendar, and the other terrible legacy date-time classes. If need be, you can convert to and fro via new conversion methods added to the old classes.

Start of day

I am trying to get the start time (00:00:00)

Do not assume the day starts at 00:00. Some dates in some zones start at another time such as 01:00. Let java.time determine the first moment of the day using LocalDate#atStartOfDay.

End of day

the end time (23:59:59) of a day

You would be missing an entire last second of the day with that approach.

Date-time work is commonly done with the Half-Open approach. In Half-Open, the beginning is inclusive while the ending is exclusive. So a day starts with the first moment of the day, and runs up to, but does not include, the first moment of the following day. Half-Open approach neatly contains that full last second of the day.

Time zones

PST time zone.

There is no such thing as a time zone named PST. Such 2-4 letter pseudo-zones are used by the popular media to indicate a hint about the time zone. But these pseudo-zones are not standardized, and are not even unique! Use only for localized presentation to humans, never for data storage or data exchange.

Real time zones are named with Continent/Region.

Perhaps by “PST” you meant “Pacific Standard Time”, which often indicates America/Tijuana, or America/Los_Angeles or America/Vancouver or others.

Or perhaps by “PST” you meant “Philippines Standard Time” covering the Asia/Manila time zone.

Example code

Capture the current moment as seen in a time zone.

ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;

Extract the date.

LocalDate today = zdt.toLocalDate() ;

Determine the first moment of the day.

ZonedDateTime zdtStartOfDay = today.atStartOfDay( z ) ;

And determine the first moment of the following day.

ZonedDateTime zdtStartOfFollowingDay = today.plusDays( 1 ).atStartOfDay( z ) ;

You may want to see the length of time. Not all days are 24 hours.

Duration d = Duration.between( zdtStartOfDay , zdtStartOfFollowingDay ) ;

Adjust both moments to UTC by extracting an Instant object. That class represents a moment as seen in UTC.

Instant start = zdtStartOfDay.toInstant() ;
Instant end = zdtStartOfFollowingDay.toInstant() ;

For each, get the count of milliseconds since the epoch reference of first moment of 1970 as seen in UTC, 1970-01-01T00:00Z.

long startMilli = start.toEpochMilli() ;
long endMilli = end.toEpochMilli() ;

However, I strongly recommend against tracking time as a count of milliseconds. This approach is confusing, as at least a couple dozen epoch reference points are commonly used. And a long cannot be interpreted by a human reader, so mistakes may go unnoticed.

Instead, data storage and data exchange should generally be done as text using the standard ISO 8601 formats. The java.time classes use these standard formats by default when parsing/generating text.

String startText = start.toString() ;
String endText = end.toString() ;

ThreeTen-Extra

You may want to add the ThreeTen-Extra library to your project. This gives you access to the Interval class, to represent a span of time as a pair of Instant objects.

Interval allDayLongToday = org.threeten.extra.Interval.of( start , end ) ;

This class provides several helpful methods. These include contains, encloses, abuts, union, intersection, and more.

Instant invoiceRecorded = … some `Instant` ;
boolean invoiceRecordedToday = allDayLongToday.contains( invoiceRecorded ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • very detailed and helpful answer. thanks a lot! – Illustrious Imp Jun 29 '22 at 20:29
  • Very instructive answer. Didn't know about ThreeTen's `Interval`. – Alexander Ivanchenko Jun 30 '22 at 11:33
  • @AlexanderIvanchenko ThreeTen-Extra also provides the equivalent for a pair of `LocalDate` objects, [`LocalDateRange`](https://www.threeten.org/threeten-extra/apidocs/org.threeten.extra/org/threeten/extra/LocalDateRange.html). – Basil Bourque Jun 30 '22 at 17:59
  • 1
    Sorry for off-topic. It seems like [this question about parsing Duration](https://stackoverflow.com/questions/72830251/datetimeparseexception-text-cannot-be-parsed-to-a-duration/72830462#72830462) has been associated with a wrong one (it has been closed as a duplicate). Current "original" question is related to `TimeUtil` and it's deprecated method [`parseDuration()`](https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/util/TimeUtil.html#parseDuration-java.lang.String-). I've requested reopening. Am I correct in this case? – Alexander Ivanchenko Jul 01 '22 at 14:58
0

Just add this section to your code:

date_format.setTimeZone(TimeZone.getTimeZone("PST"));

Then it will work as you want :)

Halil Sahin
  • 568
  • 1
  • 6
  • 25