Photo by on Heather Zabriskie Unsplash Java 8 has all its streams in all the right places, just my cup of coffee. You know what, I think I’ll take it out for a digital date. It’s Friday the 4th of August, just after 15:00 CEST. How late will we meet? No worries, I’ll figure it out. Let me just see which classes to use. Date That’s a good name! Let’s have a look. The class represents a specific instant in time, with millisecond precision. Date Yeah I need to be precise. Let’s go with this one. >>> Date = Date(); date new Look at all those dates, three in one line, this will be great. >>> System. .println( );Fri Aug 04 15:10:50 CEST 2017 out date Hey, a timezone. Where did that come from? public ()Converts this Date object to a String of the form:dow mon dd hh:mm:ss zzz yyyywhere:<snip>zzz is the time zone (and may reflect daylight saving time). Standard time zone abbreviations include those recognized by the method parse. If time zone information is not available, then zzz is empty - that is, it consists of no characters at all. String toString Ok, so that’s not an answer. Stackoverflow, you’re our only hope. What time zone does Date.toString() display? - Stack Overflow It displays using which, in turn, will default to the time zone of the operating system it is running on (i.e. the host) https://stackoverflow.com/questions/4199217/what-time-zone-does-date-tostring-display TimeZone.**_getDefault_**() Ah, so the conversion is just for display then? >>> System. .println( .getHours());15 out date What? Let’s have a look at the docs. public int () @Deprecated getHours Deprecated. As of JDK version 1.1, replaced by Calendar. (Calendar.HOUR_OF_DAY). get Oh, of course. No worries, I’ll go check out this Calendar. Calendar Calendar = Calendar.getInstance(); cal Of course, instantiation is so last decade. Singletons is where it’s at! I’m sure they took thread safety into account though. Let’s ask Stack Overflow to be sure. Is java.util.Calendar thread safe or not? - Stack Overflow Aug 26, 2012 - If you read the code you will see that none of the instance methods are synchronized, and none of the instance fields are volatile . ... In short, the Calendar class is not thread-safe, and GregorianCalendar isn't either because it inherits the non-thread-safe fields and methods. https://stackoverflow.com/questions/12131324/is-java-util-calendar-thread-safe-or-not Oh. Well. Nevermind, it’s not that important for me anyway. Let’s go see what we can do! The calendar field values can be set by calling the set methods. Getting and Setting Calendar Field Values Sure, the set methods. Like setHours and setMonth, right? public void (int field, int value)Sets the given calendar field to the given value. set Ehm, so how do you use this? cal.set(Calendar. , 20); MINUTE Of course, because the biggest advantage of having a type system is so that you can ignore it explicitly. But this is probably just the low level API, I’m sure that this is not all we have. public abstract void (int field, int amount)Adds or subtracts the specified amount of time to the given calendar field, based on the calendar's rules. add public abstract void (int field, boolean up)Adds or subtracts (up/down) a single unit of time on the given time field without changing larger fields. roll public void (int field, int amount)Adds the specified (signed) amount to the specified calendar field without changing larger fields. A negative amount means to roll down. roll What kind of an API is this? What are you talking about? Why are you rolling with dates, and what the hell does it mean to “roll down”? Does this class only make sense if you’re on a hill? Are we regularly checking up on the person who designed this thing? Because I’m not sure if he’s going to be OK. How come there are no operations for things that I actually want to do, on a level that is relevant to me? Why can’t I go to next week, or to the start or end of the day? Why do you expect me to implement all this functionality by myself every time I work with you? Java, you’re giving me second thoughts. The designers of Java’s date/time libraries. Java 8 I’m obviously behind the times though. Java 8 is where it’s at, with its all-new date/time API. What do we get? The first classes you will probably encounter when using the new API are LocalDate and LocalTime. Alright, let’s have a look. class **LocalDateTime**A date-time without a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30. Ok, no time-zone. So that means I must provide it when I want to view the date? >>> LocalDateTime = LocalDateTime.now();>>> System. .println( );2017-08-04T15:23:41.541 timePoint out timePoint Hey, that’s in my timezone. But it didn’t have timezone information. public static LocalDateTime ()Obtains the current date-time from the system clock in the default time-zone. now So you are saying… >>> System. .println( );15 out timePoint. () getHour Let’s see what the docs have to say about this. This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone. So it’s a fancy string? I mean, a time makes no sense without a timezone. You always have a timezone, even if you pretend you don’t, we’ve just seen it happen. Why not always force the user to be explicit? When is using the default time zone ever better? And why add some concept of “local” and wall clocks and hide away things that are really not that difficult? Isn’t there something simple and straightforward that I can use? An instantaneous point on the time-line. Class Instant This class models a single instantaneous point on the time-line. This might be used to record event time-stamps in the application. I’m cautiously optimistic… >>> Instant instant = Instant.now();>>> System. .println( );2017-08-04T15:28:01.354Z out instant UTC by default, that makes sense to me. This is promising! Just a simple, predictable value on the timeline, always using UTC, so I can simply convert when I need to display it it to the user. And I’m sure they’ve at least implemented a better API than the Calendar… public int (TemporalField field)Gets the value of the specified field from this instant as an int. get public Instant (long amountToAdd, TemporalUnit unit)Returns a copy of this instant with the specified amount added. plus You know what Java, I think I’ll stay home and play with my Python. It’s not all bad Let’s take a step back, because the API of LocalDateTime is actually quite nice. public static LocalDateTime (int year,int month,int dayOfMonth,int hour,int minute,int second,int nanoOfSecond)Obtains an instance of from year, month, day, hour, minute, second and nanosecond. of LocalDateTime public LocalDateTime (long weeks)Returns a copy of this with the specified number of weeks added. plusWeeks LocalDateTime This method adds the specified amount in weeks to the days field incrementing the month and year fields as necessary to ensure the result remains valid. The result is only invalid if the maximum/minimum year is exceeded. public LocalDateTime (int hour)Returns a copy of this LocalDateTime with the hour-of-day altered. withHour And there is a class that makes time zones much more explicit that implements the same API. ZonedDateTime is a date and time with a fully qualified time zone. This can resolve an offset at any point in time. class **ZonedDateTime**A date-time with a time-zone in the ISO-8601 calendar system, such as . 2007-12-03T10:15:30+01:00 Europe/Paris Let’s try it out! >>> ZonedDateTime = ZonedDateTime.now();>>> System. .println( );2017-08-04T15:33:02.325+02:00[Europe/Amsterdam]>>> System. .println(_timePoint._getHour());15>>> timePoint = timePoint.of(1983, JULY.getValue(), 20, 15, 27, 40, 0, ZoneId.of("Europe/London"));>>> System. .println( );1983-07-20T15:27:40+01:00[Europe/London]>>> _timePoint = timePoint._plusYears(30).minusHours(4)>>> System. .println( );2013-07-20T11:27:40+01:00[Europe/London] timePoint out timePoint out out timePoint out timePoint This is explicit, functional and quite elegant. The API is fluent, which makes setting specific dates or performing multiple modifications a much more civil affair. And there are no surprises in there either. Strangely, the earlier discussed classes are usually described before arriving at this one, and a lot of focus goes towards the LocalX classes. But I would suggest just using ZonedDateTime for most situations. In general, when dealing with dates and times, it’s best practice to internally treat everything as UTC explicitly. You then convert the datetime to the applicable timezone, which can be user specific, only at the point in your application where you have to display it. ZonedDateTime can facilitate this pattern just fine. The contents of this post is largely an attempt at satire and is not an accurate reflection of the thought processes or programming abilities of the author. In reality, more swearing was involved.