How JSR310 changed the way we handle date and time

hourglass with sand running
hourglass with sand running
Clear Glass with Red Sand — Nile (Pixabay)

Dealing with date and time is a cumbersome task in many programming languages. But with Java 8, the JDK provides us with a comprehensive and completely new API, changing the way we deal with time-related concepts.

Even though JSR310 was introduced with Java 8, the code example will use a Java 10 feature, local variable type inference, to improve readability.
The code examples themselves will all be Java 8 compatible, though.
The // => part of code examples will show the toString() output of the previous line/variable.

The most commonly used Stream operations

chopping board with vegetables, eggs, herbs and knife
chopping board with vegetables, eggs, herbs and knife
Photo by Katie Smith on Unsplash

The three methods, map, filter, and reduce, are the cornerstone of any functional programming.

Usually, our data pipelines consist of one or more intermediate operations, transforming (aka mapping) and/or filtering elements, and a terminal operation to gather the data again (aka reducing).

With just these three, we can do a lot, so it’s worth knowing them intimately. But they have some close relatives that can be useful, too.

Note: The article assumes Java 9. Method signatures and visibility modifiers are shortened for readability.

More concise code with simpler variable declarations

Image for post
Image for post
Different Salts @ Ponshukan, JR Niigata Station | Taken by the author

Java is often criticized as being too verbose. One aspect contributing to this characterization is the requirement to specify every type explicitly, which leads to a lot of additional noise.

A new way of declaring local variables with less clutter was given to us with JDK 10 and JEP 286: local variable type inference.

General Concept

The name itself perfectly describes the feature’s core and its limitations:

Local variable

  • Only local variables are supported
  • No methods parameters
  • No return types
  • No fields
  • No lambdas

Type inference

The Java compiler will automatically detect the correct type for us. …

When Date and Time broke in our project

Image for post
Image for post
Photo by Christine Roy on Unsplash

We use java.util.Locale to format dates, numbers, currency, and more. But in some circumstances, these formatted strings have changed with JDK 9, leading to a multitude of subtle (and sometimes not so subtle) bugs.

What Are Locales?

To better understand a problem, we must first know what we’re dealing with.

“A locale is a set of parameters that defines the user`s language, region, and any special variant preferences that the user wants to see in her user interface ”— Wikipedia

The core use of a locale is formatting many kinds of different data for output…

How the idea of a Git helper became an invaluable tool for my company

Image for post
Image for post
Photo by Vlad Tchompalov on Unsplash

I’m a great proponent of building our own tools. As developers, we perform many repetitive tasks, big and small. Many of these tasks might be made easier by using an appropriate tool instead.

We often concentrate too much on solving more significant problems. But sometimes it doesn’t need to be a real problem for a tool to be valuable. We have to find the sweet spots in our workflow.

The best investment is in the tools of one’s own trade
– Benjamin Franklin

This is the story of why and how I built a multi-repository Git CLI helper tool, Tortuga, and what I’ve learned doing it. …

Simple Ways to Improve and Secure our Scripts

Image for post
Image for post
Photo by Oskars Sylwan on Unsplash

Shell scripting is a powerful tool available on all platforms, even Windows, thanks to WSL. But it can be easy to make mistakes. Here are some tips to improve our scripts and avoid many problems.

#1: Better Shell Options

All shells have configurable options, which can be used to enable behavior. Many of them are considered safer than the shell defaults.

Fail on Errors

An absolute no-brainer is the option set -e. …

Quick Introduction to the 4 different types

Image for post
Image for post
Photo by Alberto Triano on Unsplash

In object-oriented languages, a nested or inner class is a class that’s completely declared within another class.

This allows us to combine classes that are logically bound together, to increase encapsulation, for more concise and maintainable code.

Here’s a quick, non-deep-dive overview of the 4 types of nested classes.

Static Nested Classes

A nested class is defined like any other class:

Like a static member, a static nested class is bound to the class itself, and not an instance of it. This means we can instantiate it without creating an intermediate instance of Outer

Better ways to deal with disruptive conditions in functional code

Image for post
Image for post
Photo by Randy Fath on Unsplash

In my previous articles about functional programming, I’ve shown how to incorporate a more functional style into our Java code. But I’ve omitted a crucial topic: how to deal with exceptions.

Even in my article about Java exceptions, I didn’t write about how to handle them in lambdas and streams because it deserved its own article.

Pure Functions

One of the base concepts of functional programming is that of pure functions. Pure functions generate the same output for the same input without any side effects — like affecting global state. …

Useful benchmarking is hard, but there are tools and patterns to help

Image for post
Image for post
Photo by Aron Visuals on Unsplash

Almost every developer knows the phrase “premature optimization is the root of all evil”, coined by Donald Knuth in 1974. But how are we supposed to know what is worthy of being optimized?

Our computing power improved manifold since then. But the sentiment to focus on the real issues for optimization efforts holds still true. Understanding the different kinds of latency and how to find actual relevant bottlenecks, and not only perceived ones, is the key to good benchmarking.

The Pareto Principle

It’s an axiom of business management, named after the Italian economists Vilfredo Pareto, stating

80% of sales come from 20% of clients. …

It’s not just about the best match of requirements

Image for post
Image for post
Photo by Siora Photography on Unsplash

Every time we create a new data structure, we have to decide which data types to use. Usually, the decision is simple: text most likely will become a String, non-floating-point numbers will be int, and so forth.

Most of the time, these almost subconsciously-made decisions will suffice. But to design future-proof data structures, we have to think about choosing the correct data type a little more.

Choosing the right data type

Even though the definition of “right” is highly subjective, the right data type depends on 4 different, interconnected factors:

  • What are the requirements?
  • Is it future-proof?
  • How much convenience is provided?
  • Will it impact performance or memory consumption? …


Ben Weidig

Software developer, entrepeneur, blogger. Mostly Java, sometimes Swift, Golang, Bash and all the other fun stuff.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store