-
Notifications
You must be signed in to change notification settings - Fork 8
Multi Time Zone Environment
When developing TG applications we [currently] use Date
and Joda-Time DateTime
for manipulating dates (e.g. to create now moment we may write new Date()
or new DateTime()
expression).
If we just need to persist date or to compare two dates it is perfectly okay to use java.util.Date
class and its before/after
methods for that. Things get more nuanced when we need to do some time-zone dependent manipulations:
- get day start or some concrete hour of the day (e.g.
8 PM
) - show human-readable (
toString
) date representation - midnight moment before now
-
3 AM
moment to perform some job
We need to always remember "In which time-zone?" question before making these manipulations. Currently, we create Joda-Time org.joda.time.DateTime
time-zone-aware instance and then use its methods to perform such manipulations.
If all users are in the same time-zone as a server (as specified explicitly in -Duser.timezone
) its okay to not pass actual time-zone everywhere (e.g. use new Date()
and new DateTime(...)
without time-zone, meaning it will be created in server time-zone). However, things get more messy if the user makes request in different time-zone. For example, their day start would not be the same as for the users in server time-zone.
It is important to run IDE tests, maven tests (...-[dao/web-server]/pom.xml
), PopulateDb
, Server
and Vulcanize
(!) in the intended server time-zone.
In a multi time-zone environment, where users may reside in time-zones different from the server one, it is important to create / manipulate dates using our IDates
API methods:
DateTime zoned(Date date)
DateTime now()
String toString(final Date[Time] date)
The needed time-zone may be retrieved from DateTimeZone timeZone()
method. IUniversalConstants
methods DateTime now()
and DateTime today()
are also suitable, as well as DateTime now()
in CommonEntityDao/AbstractBefore[After]ChangeEventHandler
.
Please note, that these considerations are applicable for both dependent
and independent
time-zone modes
.
-
new Date()
=>now().toDate()
-
new Date(System.currentTimeMillis())
=>now().toDate()
new Date(System.currentTimeMillis() + deltaMillis)
=>now().plus(deltaMillis).toDate()
-
new DateTime()
=>now()
-
new DateTime(date)
=>dates.zoned(date)
new DateTime(date.getTime())
=>dates.zoned(date)
- deprecated
new DateMidnight(dateTime)
=>dateTime.withTimeAtStartOfDay()
-
new DateTime(y, m, d, h, m)
=>new DateTime(y, m, d, h, m, dates.timeZone())
new DateTime(y, m, d, h, m, s)
=>new DateTime(y, m, d, h, m, s, dates.timeZone())
new DateTime(y, m, d, h, m, s, m)
=>new DateTime(y, m, d, h, m, s, m, dates.timeZone())
-
DateTime.now()
=> ournow()
-
Local[Date]Time.toDateTime[Today]()
=>Local[Date]Time.toDateTime[Today](dates.timeZone())
- TODO continue about
EntityUtils.toString
,DateTimeUtil.to[DateOnly]String
,SimpleDateFormat.format
...
(see also Bijection between client- and sever-side date/time formats #1661)
Do not use:
java.util.Calendar
Date.toString()
- any deprecated
Date
method (new Date("...")
,new Date(2024, 5, 1)
,Date.parse("...")
etc.) - any deprecated Joda-Time class (
org.joda.time.DateMidnight
)
Safe operations (if all arguments were constructed properly):
DateTime.toDate()
Date.before/after(Date other)
Date.getTime()
Date.equals(Date date)
new Date(millis)
Per aspera ad astra
- Web UI Design and Web API
- Safe Communication and User Authentication
- Gitworkflow
- JavaScript: Testing with Maven
- Java Application Profiling
- TG Development Guidelines
- Full Text Search
- Deployment recipes
- JRebel Installation and Integration
- Compile-time mechanisms