How to represent the duration of a calendar year in ISO 8601 - date

I want to define a calendar year with the ISO 8601 standard. Not a specific year, but the general duration. This has to stand for something that has a duration of exactly one calendar year, that starts on the first of January and ends on December 31.
It is not P1Y, I think, because that could be the duration of a year starting anytime. I can only come up something like: P01/12, but that seems ambiguous or not according to the standard syntax.

You may try:
--01-01/P1Y
It’s not very clear to me whether it’s valid, but I think it follows the logic of the ISO 8601 standard. it’s a time interval that begins on January 1 with no year specified and lasts a year.
A time interval is pretty clearly what you are after. According to Wikipedia:
There are four ways to express a time interval:
Start and end, such as "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"
Start and duration, such as "2007-03-01T13:00:00Z/P1Y2M10DT2H30M"
Duration and end, such as "P1Y2M10DT2H30M/2008-05-11T15:30:00Z"
Duration only, such as "P1Y2M10DT2H30M", with additional context information
So I have taken number 2. from the list.
Link: Wikipedia article ISO 8601, section Time intervals

Related

How to add TIMEZONE to VS Code User Defined Snippets?

I see the time/date variables available to VS Code User Defined Snippets are:
CURRENT_YEAR The current year
CURRENT_YEAR_SHORT The current year's last two digits
CURRENT_MONTH The month as two digits (example '02')
CURRENT_MONTH_NAME The full name of the month (example 'July')
CURRENT_MONTH_NAME_SHORT The short name of the month (example 'Jul')
CURRENT_DATE The day of the month as two digits (example '08')
CURRENT_DAY_NAME The name of day (example 'Monday')
CURRENT_DAY_NAME_SHORT The short name of the day (example 'Mon')
CURRENT_HOUR The current hour in 24-hour clock format
CURRENT_MINUTE The current minute as two digits
CURRENT_SECOND The current second as two digits
CURRENT_SECONDS_UNIX The number of seconds since the Unix epoch
Unfortunately, without TIMEZONE or TIMEZONE OFFSET from UTC, you can't automatically create an accurate, time-aware timestamp using these variables.
Example:
${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE}T${CURRENT_HOUR}:${CURRENT_MINUTE}:${CURRENT_SECOND}
Evaluates to: 2022-06-03T07:32:09, but thats not accurate enough. Without a TIMEZONE identifier, that "timestamp" is +/- 23:59:59 reflection of "actual time".
I need:
2022-06-03T07:32:09-07:00 and I want the timezone offset to adjust for daylight savings time to 2022-11-04T07:32:09-08:00 as appropriate.
Must be human readable. Not going to use Unix time.
How can I do this without spinning up a whole Extension?
I came here looking for the same thing. Its not a snippet, but I use the Insert Date String extension to handle this. You can define the default format as iso, and it comes with a key binding of ctrl-shift-alt-I. Works well enough, but I too would prefer a snippet.

Is it possible to specify an ISO Date with a timezone (i.e. GMT offset) but without a time?

I'm trying to see if you can specify a date with a timezone in ISO but without also specifying a time.
This may seem odd to ask about having a timezone without actually having a time, but technically a date represents a range between two times... the 24-hour period spanning from midnight to midnight, and that 'midnight' has to be in a timezone.
In our case, we have an API that wants to say 'Filter things on-or-before date X and on-or-after date Y' and we want the user to specify 'April 9th' (in their time zone) for both to get all things that happen on that day.
Of course we solve this by adding a day to the first date, then changing it to a pure 'before', but the front-end is required to do that math. We can't do it on the backend because having to send a date with a time means we would be sending April 9th at midnight, then on the backend adding a day to that, but what if someone passed in 4pm?
We could fail the date if it has a non-midnight time, but then we're back to why pass it in the first place.
So again, can you have a date with a timezone but not have a time component?
To decode ISO8601 dates only with year-month-day and time zone set the appropriate formatOptions of the ISO8601DateFormatter
let isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withFullDate, .withTimeZone]
If by time zone you mean a UTC offset (as used with ISO 8601 dates with times), this is no problem. If by time zone you mean a true time zone with historic, present and known future offsets from UTC, including for example summer time/DST, like America/New_York or North American Eastern Time, then ISO 8601 does not support that, neither for dates with nor without time of day.
2020-04-25-04:00
This is perfectly valid ISO 8601 for April 25 this year at offset -04:00. So you may use it for representing the interval from 2020-04-25T00:00-04:00 (inclusive) to 2020-04-26T00:00-04:00 (exclusive). Which would then be equivalent to 2020-04-25T04:00Z to 2020-04-26T04:00Z (Z meaning UTC).
Java example code
I don’t know any Swift, so cannot tell you how to format or parse such a string in Swift. In Java formatting it is not bad. Example:
LocalDate date = LocalDate.of(2020, Month.APRIL, 25);
String isoOffsetDateString = date
.atStartOfDay(ZoneId.of("America/New_York"))
.format(DateTimeFormatter.ISO_OFFSET_DATE);
System.out.println(isoOffsetDateString);
Output:
2020-04-25-04:00
I am using Java’s built-in ISO_OFFSET_DATE formatter. The documentation informs us that this formnatter is:
The ISO date formatter that formats or parses a date with an offset,
such as '2011-12-03+01:00'.
Parsing the string and producing the start and end of the day takes a little more:
TemporalAccessor parsed
= DateTimeFormatter.ISO_OFFSET_DATE.parse(isoOffsetDateString);
Instant start = LocalDate.from(parsed)
.atStartOfDay(ZoneOffset.from(parsed))
.toInstant();
Instant end = start.plus(1, ChronoUnit.DAYS);
System.out.println("From " + start + " inclusive to " + end + " exclusive");
From 2020-04-25T04:00:00Z inclusive to 2020-04-26T04:00:00Z exclusive
I have opted to convert to Instant, the class for a moment in time independent of offset or time zone. Instants print in UTC, as the trailing Z on each says. In your Java code you may prefer not to do this conversion or to do a different conversion, all depending on circumstances.
Link
Documentation of DateTimeFormatter.ISO_OFFSET_DATE

What is the last day of an ISO date range like 1970--1979?

I'm not sure if the first day of 1970--1979 is 1970-01-01 and the last day is 1979-12-31.
A quick search on Google didn't throw up the answer. Most examples would give a range such as 1970-01-01--1979-12-31 which although unambiguous, is clunkier than 1970--1979 and due to the extra detail, more prone to errors.
In "A summary of the international standard date and time notation," Markus Kuhn 1 writes:
ISO 8601 does not specify, whether its notations specify a point in
time or a time period. This means for example that ISO 8601 does not
define whether 09:00 refers to the exact end of the ninth hour of the
day or the period from 09:00 to 09:01 or anything else. The users of
the standard must somehow agree on the exact interpretation of the
time notation if this should be of any concern.
So to answer my own question, the last day of 1970--1979 is 1979-12-31 if I say that is the interpretation that I intend. Which it is!
I find ISO's lack of specification ... disturbing.

How do I express coming Monday in iso8601?

While answering Regexp matching ISO8601 date/time format I wondered how you express first coming Monday or repeat every monday in ISO8601.
My guess would be something like:
W-1
R/W-1
But I cannot find a confirmation of that.
ISO 8601 has the concept of week dates which allow you to specify a week of the year and the day of the year. In the following example 2014-W01-1 means the first week of 2014 on Monday. Then repeat that every week using P1W
R/2014-W01-1T00:00:00/P1W
Seen in this answer

FormCalc Date function doesn't returns current system date

How do I get date function to return date according to current system date?
Right now, with the code snippet below, it always returns UK time, not the current system date.
<calculate>
<script>$ = concat( num2date(date(), DateFmt()), " ", num2Time(Time(), TimeFmt()) )</script>
Any help is appreciated!
It's probably not UK time exactly, but rather GMT (or UTC, to use a more precise term). The UK happens to be aligned to GMT in the winter, but in the summer it advances one hour to BST for daylight saving time.
Now, I've never used LiveCycle myself, but nonetheless, I've read through the somewhat minimal docs for LiveCycle FormCalc Date and Time Functions, and the spec, and it appears to me that a few critical mistakes were made.
The date and time functions return UTC-based values, but only the time-related functions have been made aware of the local time zone. That is, there are separate Num2Time and Num2GMTime functions, but there is only one Num2Date function.
The Num2Date function works in terms of whole integer days, and thus they are simply days since 1900-01-01. Therefore, the number being passed in to the function must already be representative of the desired time zone. However, the Date function only gets the current GMT date. There does not appear to be a function to get the current local date.
It's different on the time side, because of the millisecond precision involved. However, there's yet another flaw here. Despite the docs saying that the Time function returning "the number of milliseconds since the epoch", its actually returning only the number of milliseconds since midnight GMT. There is no day-over-day accumulation of milliseconds from the date part. The docs here are even lying in their sample code which says:
Returns the current system time as the number of milliseconds since the epoch.
Time() => 71533235 at precisely 3:52:15 P.M. on September 15th, 2003 to a user in the Eastern Standard Time (EST) zone.
If that was indeed the case (and ensuring to use their 1900-01-01 epoch), the value would actually include an additional 3272572800000 milliseconds representing the days between 1900-01-01 and 2003-09-15, bringing the total timestamp to 3272644333235. Additionally, there's a typo there, because the timestamp they give is 3:52:13, not 3:52:15. Clearly nobody paid close attention to these docs!
The real problem is that one cannot be certain that the number of milliseconds since midnight of the current day in the local time zone is the same on every day. If instead of getting the current time, you were working with past stored time values, you might be an hour off (+ or -) if the current offset is different due to daylight saving time. Example: Eastern time might be UTC-5 or UTC-4, but only the offset currently in effect will be used by the Num2Time function, even if the date you're working with is using the other offset.
So, in summary, the Date function is insufficient, leading to your observations, and the date/time functionality in general is poorly designed. Given the constraints of this API, I can't even recommend a workaround. There would have to be a LocalDate function of some kind to be used instead of the Date function, but it doesn't exist.
The only advice I can offer is that it appears (from my research, not experience) that LiveCycle can use either FormCalc or JavaScript. So - use JavaScript instead.