-
Notifications
You must be signed in to change notification settings - Fork 0
/
java-basics-dates-and-time.html
39 lines (37 loc) · 24.1 KB
/
java-basics-dates-and-time.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!DOCTYPE html><html lang="de-ch"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Java basics: Dates and Time - Finecloud</title><meta name="description" content="Local date Now Let's start with the basics, we just want to represent the date today and print that local date now: public class TimeTest { public static void main(String[] args) { LocalDate now = LocalDate.now(); System.out.println(now); } } output: 2022-08-29 Process finished with exit…"><meta name="generator" content="Publii Open-Source CMS for Static Site"><link rel="stylesheet" href="https://www.finecloud.ch/media/plugins/syntaxHighlighter/prism-black.css"><link rel="canonical" href="https://www.finecloud.ch/java-basics-dates-and-time.html"><link rel="alternate" type="application/atom+xml" href="https://www.finecloud.ch/feed.xml"><link rel="alternate" type="application/json" href="https://www.finecloud.ch/feed.json"><meta property="og:title" content="Java basics: Dates and Time"><meta property="og:site_name" content="Finecloud"><meta property="og:description" content="Local date Now Let's start with the basics, we just want to represent the date today and print that local date now: public class TimeTest { public static void main(String[] args) { LocalDate now = LocalDate.now(); System.out.println(now); } } output: 2022-08-29 Process finished with exit…"><meta property="og:url" content="https://www.finecloud.ch/java-basics-dates-and-time.html"><meta property="og:type" content="article"><link rel="shortcut icon" href="https://www.finecloud.ch/media/website/finecloud.png" type="image/png"><link rel="stylesheet" href="https://www.finecloud.ch/assets/css/style.css?v=39da73365516a098a9b73b721fc970e2"><script type="application/ld+json">{"@context":"http://schema.org","@type":"Article","mainEntityOfPage":{"@type":"WebPage","@id":"https://www.finecloud.ch/java-basics-dates-and-time.html"},"headline":"Java basics: Dates and Time","datePublished":"2022-08-30T16:28","dateModified":"2022-08-30T18:55","description":"Local date Now Let's start with the basics, we just want to represent the date today and print that local date now: public class TimeTest { public static void main(String[] args) { LocalDate now = LocalDate.now(); System.out.println(now); } } output: 2022-08-29 Process finished with exit…","author":{"@type":"Person","name":"Finecloud","url":"https://www.finecloud.ch/authors/finecloud/"},"publisher":{"@type":"Organization","name":"Finecloud"}}</script><meta name="google-site-verification" content="seFY9U12uiEq5U3_MyZiX6XWzk0AVFl9zITr2ZKsytY"></head><body><div class="site-container"><header class="top" id="js-header"><a class="logo" href="https://www.finecloud.ch/">Finecloud</a><nav class="navbar js-navbar"><button class="navbar__toggle js-toggle" aria-label="Menu" aria-haspopup="true" aria-expanded="false"><span class="navbar__toggle-box"><span class="navbar__toggle-inner">Menu</span></span></button><ul class="navbar__menu"><li><a href="https://www.finecloud.ch/" target="_self">Blog</a></li><li><a href="https://www.finecloud.ch/tags/" target="_self">Tags</a></li></ul></nav><div class="search"><div class="search__overlay js-search-overlay"><div class="search__overlay-inner"><form action="https://www.finecloud.ch/search.html" class="search__form"><input class="search__input js-search-input" type="search" name="q" placeholder="search..." aria-label="search..." autofocus="autofocus"></form><button class="search__close js-search-close" aria-label="Close">Close</button></div></div><button class="search__btn js-search-btn" aria-label="Search"><svg role="presentation" focusable="false"><use xlink:href="https://www.finecloud.ch/assets/svg/svg-map.svg#search"/></svg></button></div></header><main><article class="post"><div class="hero"><figure class="hero__image hero__image--overlay"><img src="https://www.finecloud.ch/media/website/download.jpg" srcset="https://www.finecloud.ch/media/website/responsive/download-xs.jpg 300w, https://www.finecloud.ch/media/website/responsive/download-sm.jpg 480w, https://www.finecloud.ch/media/website/responsive/download-md.jpg 768w, https://www.finecloud.ch/media/website/responsive/download-lg.jpg 1024w, https://www.finecloud.ch/media/website/responsive/download-xl.jpg 1360w, https://www.finecloud.ch/media/website/responsive/download-2xl.jpg 1600w" sizes="100vw" loading="eager" alt=""></figure><header class="hero__content"><div class="wrapper"><div class="post__meta"><time datetime="2022-08-30T16:28">August 30, 2022</time></div><h1>Java basics: Dates and Time</h1></div></header></div><div class="wrapper post__entry"><div class="post__toc"><h3>Table of Contents</h3><ul><li><a href="#mcetoc_1gbmeuk7f4r">Local date</a><ul><li><a href="#mcetoc_1gbmfa47955">Now</a></li><li><a href="#mcetoc_1gbmeuk7f4s">Set a Date</a></li><li><a href="#mcetoc_1gbmeuk7f4u">Dates until</a></li></ul></li><li><a href="#mcetoc_1gbmfa47956">Local Time</a><ul><li><a href="#mcetoc_1gbmgm59995">Now</a></li><li><a href="#mcetoc_1gbmgm59996">Set a time</a></li></ul></li><li><a href="#mcetoc_1gbmgm59997">Local date time</a></li><li><a href="#mcetoc_1gbmuqcgbb6">Measuring how much time elapsed</a></li><li><a href="#mcetoc_1gbmuqcgbb7">Instant</a></li><li><a href="#mcetoc_1gbmvuoobba">Time Zones</a></li><li><a href="#mcetoc_1gbnqrvhujl">Temporal Adjuster</a></li><li><a href="#mcetoc_1gbnqrvhujm">Immutability</a></li></ul></div><h2 id="mcetoc_1gbmeuk7f4r">Local date</h2><h3 id="mcetoc_1gbmfa47955">Now</h3><p>Let's start with the basics, we just want to represent the date today and print that local date now:</p><pre class="hljs" style="color: #a9b7c6; background: #282b2e none repeat scroll 0% 0%; display: block; overflow-x: auto; padding: 0.5em;"><span class="hljs-keyword" style="color: #cc7832;">public</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #cc7832;">class</span> <span class="hljs-title" style="color: #ffc66d;">TimeTest</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #cc7832;">public</span> <span class="hljs-keyword" style="color: #cc7832;">static</span> <span class="hljs-keyword" style="color: #cc7832;">void</span> <span class="hljs-title" style="color: #ffc66d;">main</span><span class="hljs-params">(String[] args)</span> </span>{
LocalDate now = LocalDate.now();
System.out.println(now);
}
}</pre><p>output: <br><code>2022-08-29</code><br><br><code>Process finished with exit code 0</code><br><br>What if we want to pick a specific date in the future of today? We can use the plusDays, plusWeeks, plusMonths or plusYears for this:<br><br><code> System.out.println(now.plusYears(5));</code><br><br>output: <br><code>2027-08-29</code><br><br><code>Process finished with exit code 0</code><br><br>If you want a more generic way you can also use this:<br><br><code> System.out.println(now.plus(3, ChronoUnit.YEARS));</code><br><br>output:<br><code>2025-08-29</code><br><br><code>Process finished with exit code 0</code><br><br>There is also a minus Method, which does exactly the opposite of the plus method.</p><h3 id="mcetoc_1gbmeuk7f4s">Set a Date</h3><p>There is a method, which allows you to specify a year, month and a day of month:<br><br><code> LocalDate newYears = LocalDate.of(2020,1,1);</code><br><code> System.out.println(newYears);</code><br><br>output:<br><code>2020-01-01</code><br><br><code>Process finished with exit code 0</code><br><br>Let's say that we wanted to know what day of the week was New Year's Day in 2020. That's really easy to do because there are some really convenient methods on our local date classes to give us that kind of information so we can do a get.<br><br><code> System.out.println(newYears.getDayOfWeek());</code><br><br>output:</p><p><code>WEDNESDAY</code><br><br><code>Process finished with exit code 0</code><br><br><br>Same exists for:</p><ul><li>getDayOfMonth</li><li>getDayOfYear</li><li>getMonth</li></ul><h3 id="mcetoc_1gbmeuk7f4u">Dates until</h3><p>This returns a stream of local dates between the New Years date and now, for example. We can use the streams API and lambdas on Date: if we do something like a for each, we can print out each of these dates:<br><br><code> System.out.println(newYears.getDayOfWeek());</code><br><code> newYears.datesUntil(LocalDate.now())</code><br><code> .forEach(System.out::println);</code><br><br><br>output: <br><br><code>2020-01-01</code><br><code>2020-01-02</code><br><code>..</code><br><code>2022-08-26</code><br><code>2022-08-27</code><br><code>2022-08-28</code><br><br><code>Process finished with exit code 0</code><br><br>If you didn't want that to generate each and every single day, you can actually specify with an overloaded version of the *datesUntil* method a period, like so:<br><br><code> newYears.datesUntil(LocalDate.now(), Period.ofMonths(1))</code><br><code> .forEach(System.out::println);</code><br><br>output:<br><br><code>2020-01-01</code><br><code>2020-02-01</code><br><code>...</code><br><code>2022-06-01</code><br><code>2022-07-01</code><br><code>2022-08-01</code><br><br><code>Process finished with exit code 0</code><br><br></p><h2 id="mcetoc_1gbmfa47956">Local Time</h2><p>The class local dates is quite similar to the local dates class and very helpful. Basically, all the things that we can do that make sense with local date, we can also do with local time.</p><h3 id="mcetoc_1gbmgm59995">Now</h3><pre class="hljs" style="color: #a9b7c6; background: #282b2e none repeat scroll 0% 0%; display: block; overflow-x: auto; padding: 0.5em;"><span class="hljs-keyword" style="color: #cc7832;">public</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #cc7832;">class</span> <span class="hljs-title" style="color: #ffc66d;">TimeTestTime</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #cc7832;">public</span> <span class="hljs-keyword" style="color: #cc7832;">static</span> <span class="hljs-keyword" style="color: #cc7832;">void</span> <span class="hljs-title" style="color: #ffc66d;">main</span><span class="hljs-params">(String[] args)</span> </span>{
LocalTime now = LocalTime.now();
System.out.println(now);
}
}</pre><p>output:</p><p><code>06:17:48.708787</code><br><br><code>Process finished with exit code 0</code><br><br>Please note: <strong>Local date represents literally a date with no time component associated with it. Local time represents a time with no date associated with it.</strong></p><h3 id="mcetoc_1gbmgm59996">Set a time</h3><p>Of course you can also create a custom time and compere one time object with another:</p><p><code> LocalTime lt1 = LocalTime.of(10,30);</code><br><code> LocalTime lt2 = LocalTime.of(10,31);</code><br><code> System.out.println(lt1.equals(lt2));</code></p><p>output:</p><p><code>false</code><br><br><code>Process finished with exit code 0</code></p><h2 id="mcetoc_1gbmgm59997">Local date time</h2><p>This class allows us the full culmination of having both the date and the time together. Here we can specify a year, month, day, minute, year, month, day of month, hour, minute, second, nanoseconds. We can even build a local date time out of a local date and a local time, which makes sense, right?</p><pre class="hljs" style="color: #a9b7c6; background: #282b2e none repeat scroll 0% 0%; display: block; overflow-x: auto; padding: 0.5em;"><span class="hljs-keyword" style="color: #cc7832;">public</span> <span class="hljs-class"><span class="hljs-keyword" style="color: #cc7832;">class</span> <span class="hljs-title" style="color: #ffc66d;">TimeTestDateTime</span> </span>{
<span class="hljs-function"><span class="hljs-keyword" style="color: #cc7832;">public</span> <span class="hljs-keyword" style="color: #cc7832;">static</span> <span class="hljs-keyword" style="color: #cc7832;">void</span> <span class="hljs-title" style="color: #ffc66d;">main</span><span class="hljs-params">(String[] args)</span> </span>{
LocalDate ld1 = LocalDate.of(<span class="hljs-number" style="color: #6897bb;">2000</span>,<span class="hljs-number" style="color: #6897bb;">1</span>,<span class="hljs-number" style="color: #6897bb;">1</span>);
LocalTime lt1 = LocalTime.of(<span class="hljs-number" style="color: #6897bb;">10</span>,<span class="hljs-number" style="color: #6897bb;">30</span>);
LocalDate ld2 = LocalDate.of(<span class="hljs-number" style="color: #6897bb;">2000</span>,<span class="hljs-number" style="color: #6897bb;">1</span>,<span class="hljs-number" style="color: #6897bb;">1</span>);
LocalTime lt2 = LocalTime.of(<span class="hljs-number" style="color: #6897bb;">10</span>,<span class="hljs-number" style="color: #6897bb;">30</span>);
LocalDateTime ltd1 = LocalDateTime.of(ld1,lt1);
LocalDateTime ltd2 = LocalDateTime.of(ld2,lt2);
System.out.println(ltd1.equals(ltd2));
}
}</pre><p>output:</p><p><code>true</code><br><br><code>Process finished with exit code 0</code><br><br></p><h2 id="mcetoc_1gbmuqcgbb6">Measuring how much time elapsed</h2><p>You can easily just extract the local date from a local date time or the local time from a local date time. Or we can calculate the difference between two dates:</p><p><code> Period diff = Period.between(ld1, ld2);</code><br><code> System.out.printf("%d years, %d months, %d days%n", diff.getYears(), diff.getMonths(), diff.getDays());</code></p><p>output:</p><p><code>2 years, 5 months, 9 days</code><br><br><code>Process finished with exit code 0</code></p><p>The<em> period </em>method allows us measuring differences in terms of days, weeks, months and years. The first argument is meant to be the starting point or the earlier date, and then the second argument is meant to be the later date.</p><p>If we want to measure in smaller terms of just days, lets say we want to know the elapsed hours, minutes, seconds or milliseconds between two times, then we need to use the <em>duration</em> method, just like we used the <em>period</em> method before. For each duration method there is a <em>toX</em> method as well as a <em>toXPart</em> method. The <em>toHoursPart</em> method simply gives us back the actual number for the hours that we were receiving in the original duration object itself when we just called to string on the duration itself. This is just returning back the hours portion of that, whereas the <em>toHours</em> method, actually just takes the total number of seconds for the entire duration and divides it by 3600 being the number of seconds in an hour.</p><h2 id="mcetoc_1gbmuqcgbb7">Instant</h2><p>Instant is actually quite similar, to local date time, except that local date, local time and local date time are really all meant for human consumption. So if you're writing programs that are going to be dealing with dates and times that are meant for humans to enter or to read, you'd want to be using these classes generally speaking.</p><p>On the other hand, though functionally somewhat similar to the local date, time has a different purpose, and that is for machines to share timing with each other.</p><p><code> System.out.println(Instant.now());</code></p><p>output:</p><p><code>2022-08-30T08:37:45.926007Z</code><br><br><code>Process finished with exit code 0</code></p><p>But the instant actually tracks time in terms of seconds. And this is actually part of a legacy in computing that dates back to a specific date in time 1970 January 1st, which is known as epoch time. The creators of the very popular operating system Unix chose to track time in their operating system from that date. And that's around the period of time when Unix was released. So that's kind of the birth time of Unix. And so they just chose 1970 January 1st, and presumably because so many programs written from that period of time forward used this notion of time tracking called the epoch time. It has persisted to this day, which is kind of weird when you really think about it. There may be times as a developer when you need to specify dates and times to other systems. Some of these other systems may require that you pass them date time information using epoch time. And if you need to do that, you can use the instant class to do so.</p><h2 id="mcetoc_1gbmvuoobba">Time Zones</h2><p>What if you have a WebApp which is used worldwide over different timezones? Which time should you use to save the data? How can you guarantee that the timestamps over different timezones are correctly displayed for each user?</p><p>Luckily there is a class to help us: <em>ZonedDateTime</em>. You need to provide a <em>LocalDate</em> or <em>LocalDateTime</em> as well as a <em>ZoneId</em>. If you use <em>ZoneId.systemDefault()</em> then Java uses the Timezone of your local Computer. Keep in mind that most often your software will run on a server and you don't want to use the timezone of your server, because most often your server does not run in the same TimeZone as you are:</p><p><code>System.out.println(ZonedDateTime.of(ltd1, ZoneId.systemDefault()));</code></p><p>example output:</p><p><code>2000-01-01T10:30+01:00[Europe/Zurich]</code><br><br><code>Process finished with exit code 0</code></p><p>but we can set the Timezone to anything we want, like so:</p><p><code>System.out.println(ZonedDateTime.of(ltd1, ZoneId.of("-5")));</code></p><p>output:</p><p><code>2000-01-01T10:30-05:00</code></p><p>One possible thing which we could do to solve the time difference between users, is that we could normalize the time in one standard time zone, which will typically be UTC. We need to store everything in UTC on the Server.</p><p>Let's say that our users want their message to be sent at moon on Christmas. And let's also say that our user lives in Switzerland, this is the information that get's transmitted from their Web browser to our servers. So far we have the information about the xmas date and time, as well as the users TimeZone:</p><p><code> LocalDateTime xmas = LocalDateTime.of(2022,12,25,12,00);</code><br><code> // Switzerland - GMT+01</code><br><code> ZonedDateTime zxmas = ZonedDateTime.of(xmas, ZoneId.of("+1"));</code></p><p>to normalize this, we can now use this:</p><p><code> System.out.println(zxmas.withZoneSameInstant(ZoneId.of("+0")));</code></p><p>output:</p><p><code>2022-12-25T11:00Z</code><br><br><code>Process finished with exit code 0</code></p><p>And this is finally the information we want to store in the database, if the database does not support TimeZones.</p><p><strong>If you have a greenfield approach, or if you can control the database as much as your want, you should go ahead and store the Date, Time and TimeZone information all together in the database.</strong></p><h2 id="mcetoc_1gbnqrvhujl">Temporal Adjuster</h2><p>This is a weird name as long as you don't know what it is for. This class allows us to make adjustments to time. What does that mean? It means warping time in ways that humans might say in English, like for example, the Friday after next, or the next Thursday and things like that. So let's say you wanted to figure out the next Tuesday from that date on <em>d1:</em></p><p><code>System.out.println(ld1.with(TemporalAdjusters.next(DayOfWeek.TUESDAY)));</code></p><p>output:</p><p><code>2000-01-04</code><br><br><code>Process finished with exit code 0</code></p><p>So basically, what this means is from the date that we're specifying here the <em>d1</em>, whatever that date is, create another date that starts at that same point in time <em>d1</em> and then generate a new date, which would represent the next and then whatever day of the week in this particular case. There are a lot more methods on the TermporalAdjusters like <em>lastDayOfYear, lastDayOfMonth, firstInMonth</em> only to name a few.</p><h2 id="mcetoc_1gbnqrvhujm">Immutability</h2><p>All of these new daytime classes <em>LocalDate, LocalTime, LocalDate, TimeZone, DateTime,</em> et cetera are all designed to be immutable. Immutable is a term that you'll hear from time to time in software development, and it just means that you can't change the properties of that object after it has been created. This is considered to be a very desirable trait of objects frequently in programming, especially when you deal with functional programming styles.</p><p>So the <em>DateTime</em> API just embraces the immutable pattern throughout, but that comes with some consequences. That means that when we create an instance of a local data or time or any of these other classes, and we want to change some property of one of those objects, we can't just make a change. Instead, what we can do is we can basically clone an object and change things in the clone as it's being cloned.</p><p><code>System.out.println(ld1.withMonth(3).withDayOfMonth(15));</code></p><p>output:</p><p><code>2000-03-15</code><br><br><code>Process finished with exit code 0</code></p><p> </p></div><footer class="wrapper post__footer"><p class="post__last-updated">This article was updated on August 30, 2022</p><ul class="post__tag"><li><a href="https://www.finecloud.ch/tags/java/">java</a></li><li><a href="https://www.finecloud.ch/tags/java-basics/">java basics</a></li><li><a href="https://www.finecloud.ch/tags/lambda/">lambda</a></li><li><a href="https://www.finecloud.ch/tags/linux/">linux</a></li><li><a href="https://www.finecloud.ch/tags/softwareentwicklung/">software development</a></li><li><a href="https://www.finecloud.ch/tags/stream-api/">stream-api</a></li></ul><div class="post__share"></div></footer></article><nav class="post__nav"><div class="post__nav-inner"><div class="post__nav-prev"><svg width="1.041em" height="0.416em" aria-hidden="true"><use xlink:href="https://www.finecloud.ch/assets/svg/svg-map.svg#arrow-prev"/></svg> <a href="https://www.finecloud.ch/java-basics-optionals.html" class="post__nav-link" rel="prev"><span>Previous</span> Java basics: Optionals</a></div><div class="post__nav-next"><a href="https://www.finecloud.ch/infrastructure-as-software.html" class="post__nav-link" rel="next"><span>Next</span> Infrastructure as Software </a><svg width="1.041em" height="0.416em" aria-hidden="true"><use xlink:href="https://www.finecloud.ch/assets/svg/svg-map.svg#arrow-next"/></svg></div></div></nav><div class="post__related related"><div class="wrapper"><h2 class="h5 related__title">You should also read:</h2><article class="related__item"><div class="feed__meta"><time datetime="2022-05-26T14:07" class="feed__date">Mai 26, 2022</time></div><h3 class="h1"><a href="https://www.finecloud.ch/java-collection-iteratoren.html">Java Collection Iteratoren</a></h3></article><article class="related__item"><div class="feed__meta"><time datetime="2022-05-26T13:28" class="feed__date">Mai 26, 2022</time></div><h3 class="h1"><a href="https://www.finecloud.ch/java-collection-sets.html">Java Collection Sets</a></h3></article><article class="related__item"><div class="feed__meta"><time datetime="2022-05-26T13:19" class="feed__date">Mai 26, 2022</time></div><h3 class="h1"><a href="https://www.finecloud.ch/java-collection-listen.html">Java Collection Listen</a></h3></article></div></div></main><footer class="footer"><div class="footer__copyright"><p>Powered by Publii</p></div><button onclick="backToTopFunction()" id="backToTop" class="footer__bttop" aria-label="Back to top" title="Back to top"><svg><use xlink:href="https://www.finecloud.ch/assets/svg/svg-map.svg#toparrow"/></svg></button></footer></div><script>window.publiiThemeMenuConfig = {
mobileMenuMode: 'sidebar',
animationSpeed: 300,
submenuWidth: 'auto',
doubleClickTime: 500,
mobileMenuExpandableSubmenus: true,
relatedContainerForOverlayMenuSelector: '.top',
};</script><script defer="defer" src="https://www.finecloud.ch/assets/js/scripts.min.js?v=6ca8b60e6534a3888de1205e82df8528"></script><script>var images = document.querySelectorAll('img[loading]');
for (var i = 0; i < images.length; i++) {
if (images[i].complete) {
images[i].classList.add('is-loaded');
} else {
images[i].addEventListener('load', function () {
this.classList.add('is-loaded');
}, false);
}
}</script><script defer="defer" src="https://www.finecloud.ch/media/plugins/syntaxHighlighter/prism.js"></script></body></html>