ZoneOffset and OffsetDateTime from java.time
Consider using java.time, the modern Java date and time API, for your date and time work. Nautical (or military) time zones are mere offsets in whole hours from UTC, so we don’t need any fancy time zone rules taking summer time (DST) and other anomalies into account, for there aren’t any. A plain ZoneOffset
will do.
The time zone names are not built in. We need to code the conversion ourselves. One way to do it is through an array in which we can look up a time zone name and get the offset out:
private static final int[] offsetPerNauticalTimeZone = new int['Z' + 1];
private static final int invalid = -100;
static {
Arrays.fill(offsetPerNauticalTimeZone, invalid);
// The letter "Z" ("Zulu") indicates Coordinated Universal Time (UTC).
offsetPerNauticalTimeZone['Z'] = 0;
// A through M denote positive offsets, but J is skipped
for (int offset = 1; offset <= 9; offset++) {
offsetPerNauticalTimeZone['A' - 1 + offset] = offset;
}
for (int offset = 10; offset <= 12; offset++) {
offsetPerNauticalTimeZone['K' - 10 + offset] = offset;
}
// N through Y are the negative offsets
for (int negatatedOffset = 1; negatatedOffset <= 12; negatatedOffset++) {
offsetPerNauticalTimeZone['N' - 1 + negatatedOffset] = -negatatedOffset;
}
}
Example use:
char nauticalTimeZone = 'A'; // Set desired letter here
int offsetHours = offsetPerNauticalTimeZone[nauticalTimeZone];
if (offsetHours == invalid) {
System.out.println("Invalid nautical time zone " + nauticalTimeZone);
} else {
ZoneOffset offset = ZoneOffset.ofHours(offsetHours);
OffsetDateTime runDateTime = OffsetDateTime.now(offset);
System.out.println(runDateTime);
}
When I ran this snippet just now, the output was:
2020-09-23T20:05:52.451+01:00
You notice that the offset is +01:00 corresponding to nautical time zone A. Please try the other time zones too.
As the code stands it will throw anArrayIndexOutOfBounsException
if the char is beyond upper case Z
. I leave it to you to build in the necessary check.
Edit:
Well, the calendar code I am using does accept time zone names. I just
need a complete list of what those are.
If that were me, I would take the opportunity to switch over from the outdated Calendar
class to java.time. Also because, as I tried to indicate, when you use the old-fashioned TimeZone
class, you are carrying with you everything that is needed for general time zones when all you need is an offset. If you insist on using Calendar
and feeding it a TimeZone
, the conversion is easy enough. Assuming your are using ThreeTenABP (see below):
TimeZone oldfashionedTimeZone = DateTimeUtils.toTimeZone(offset);
System.out.println(oldfashionedTimeZone.getID());
GMT+01:00
This is the time zone ID you were asking for. The others are similar, you can construct them yourself. If in doubt, run my code at get them from there. For feeding into a Calendar
you don’t need the ID, of course, you have already got the TimeZone
object.
Still a bit better (or not quite so bad), even if you need an old-fashioned Calendar
for your legacy code, you don’t need to deal with the confusing and poorly designed TimeZone
class. You may get your Calendar
from this code:
Calendar runDate = DateTimeUtils.toGregorianCalendar(
runDateTime.atZoneSameInstant(offset));
If using Java 8 (also if using Java 8 through desugaring, I suppose), the conversions are a bit shorter still, TimeZone.getTimeZone(offset)
and GregorianCalendar.from(runDateTime.atZoneSameInstant(offset))
, respectively.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
- In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
- On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from
org.threeten.bp
with subpackages.
Links