Best way to present the ambiguous extra hour when winter time begins - timezone

What is the standard way to present the ambiguous extra hour when winter time begins?
So far i used localized time formats to display and parse dates and times. E.g. 1. January 2014, 15:27.
I'm using location based time zones like "Europe/Berlin".
And i can't just change to plain GMT offsets because i do need to perform calculations on the dates. Otherwise i would get the wrong absolute time when moving across DST change dates.
All this works fine except for the one hour at the end of DST (e.g. October 26th 2014, 2am-3am) which occurs twice. I need to present it in a way that i can later parse again.
Is there a stadardized format? Do i just add a custom symbol? Do i use the GMT offset additionally to the geographic time zone? And how do i know when to use this special format - because i don't want to print it all the time, since it's redundant most of the year.

The answer by Matt Johnson is correct and insightful.
Java 8 & java.time.*
Let me add another to his list, from the new java.time.* classes bundled with Java 8 and defined by JSR 310. These new classes are inspired by Joda-Time but are re-architected.
The default used by java.time.ZonedDateTime is one concatenated string using square brackets around the time zone name and no spaces.
2014-10-26T13:49:48.278+01:00[Europe/Berlin]
#MattJohnson Feel free to merge this answer's content with yours if you wish.

There isn't a standard that combines everything. The closest you can get is with two fields. One which would be an ISO8601/RFC3339 Date+Time+Offset, and another which would be the IANA/Olson time zone.
Depending on your platform, you may have a single object that represents both, such as a DateTime in Joda-Time or a ZonedDateTime in Noda Time. But there is no standardized representation of this as a string.
Here are some that I have seen though:
Two completely separate strings:
"2014-10-26T02:00:00+01:00"
"Europe/Berlin"
One concatenated string, space separated:
"2014-10-26T02:00:00+01:00 Europe/Berlin"
One concatenated string with a space and using parentheses:
"2014-10-26T02:00:00+01:00 (Europe/Berlin)"
One concatenated string without any space, but with square brackets: (thanks Basil)
"2014-10-26T02:00:00+01:00[Europe/Berlin]"
As JSON, with some predetermined field names:
{
value: "2014-10-26T02:00:00+01:00",
zone: "Europe/Berlin"
}
As XML, with some predetermined attribute names:
<TimeStamp Value="2014-10-26T02:00:00+01:00" Zone="Europe/Berlin" />
As XML, with some predetermined element names:
<TimeStamp>
<Value>2014-10-26T02:00:00+01:00</Value>
<Zone>Europe/Berlin</Zone/>
</TimeStamp>
Any of these would be acceptable. Pick the one that fits your situation, or adapt to something similar.
Regarding your question:
... how do i know when to use this special format ...
When you're recording an event that has already passed and cannot be changed, then you do not need to store the time zone. The date+time+offset value alone is sufficient. Otherwise, you need both.

Related

ISO8601 with Timezone and Timespan

I've read I can add timezone information on an ISO8601 date by appending for example Z or +02 or -03:00.
I've also read that I can add timespan information by appending a P and then the time, for example 4DT2H (4 days and two hours).
How can I combine the two? Timezone or timespan first?
E.g. 2018-10-18T14:20+02P1D vs 2018-10-18T14:20P1D+02
By having two values, you are basically describing when an event starts, and how long it lasts. Such values are covered in section 4.4.4.3 of the ISO 8601 specification, titled "Representations of time interval identified by start and duration".
The spec requires full compliance with the established formats for both the timestamp and the time period parts, separating them with a forward slash (/) character.
For example: 2018-10-18T14:20+02/P1D
The time zone offset (whether Z, or +02, or -03:00) belongs with the timestamp, before the slash.
That said, I know of few parsers that understand this format. It is compliant, but not every parser of ISO 8601 necessarily understands every part of the spec.

Find a time in some text, allowing for multiple formats

I have the following formula.
=INDEX(Lookups!$L$1:$L$726,MAX(IF(ISERROR(FIND(Lookups!$L$1:$L$726,$A1)),-1,1)*(ROW(Lookups!$L$1:$L$726)-ROW(Lookups!$L$1)+1)))
The idea is to pick up the time for a certain item from an email (already parsed into google sheets). The emails come in various formats so I'm unable to specify the location in the the text string to look at specifically.
The times are not always written in a conventional time format either so as you can see from the formula there are 726 possibilities that I work with. For example, sometimes the time could be written as 13:15 and others as 1:15 or even 1.15 or 1-15 etc etc.
The issue I have is that the above formula seems to start with the smallest string possible and work 'upwards', therefore picking up 3:15 from the email string rather than the full time string which is 13:15. Is there a way I can amend the formula to search for the longest string first, in that example looking for 13:15 and then only searching for 3:15 if the prior is not found.
Hope that makes sense. Thanks in advance for any assistance.
One way is to reorder those 726 possibilities so that you have the longer ones first. You can do it by creating another column with =len(L1), copying that formula down, and sorting the range by this new column in descending order.
But it would be easier to use regexextract instead, because regular expressions are designed to solve the problem you are facing. For example,
=regexextract(L1, "\b\d{1,2}[:.-]\d{1,2}\b")
picks up all of the variants 1:15, 13:15, 1-15 or 13.15. (It looks for the following sequence: word boundary, 1-2 digits, one of characters :, ., -, then 1-2 digits, and another word boundary.) The match is greedy, so it will find 13:15 when it's there, not just 3:15.
A more complex form
=regexextract(L1, "(?i)\b\d{1,2}[:.-]\d{1,2} ?(?:am|pm)?\b")
also supports "am" or "pm" after the time, case-insensitive and possibly separated by a space from the digits.
This can be refined further, for example the hours part would be more precisely stated as [0-2]?\d instead of \d{1,2}, and the minutes part as [0-6]?\d.

Overriding the system Date Format

In my application I am reading from one database and writing to a second. The app is quick and dirty so I am reading / writing using AsString on both the FieldByName and ParamByName of the queries.
This works for all my use cases apart from where the data type is Date or DateTime
As far as I can tell FieldByName.AsString uses the system ShortDateTime format to return dates as (in my case) dd/mm/yyyy. The database expects the date to be written in as yyyy-mm-dd
According to Delphi Basics I should be able to set ShortDateFormat to what I need, but it appears that in XE5 this is no longer the case (correct?)
Further digging on here returns these two questions that use TFormatSettings to override the local settings. However, both of these use the resulting FormatSettings in StrToDate and FormatDateTime directly.
So two questions
1) Can I tell my application to override the System ShortDateFormat?
2) If so, How (I have a Plan B if not)?
The use of a global variable for the date and time formats was a mistake committed long ago by the original RTL designers. Functions that rely on the global format settings, like the single parameter StrToDate are retained for backwards compatibility, but you should not be using them.
For conversions between date/time and string you should:
Initialise a TFormatSettings instance with your date format.
Call the two parameter StrToDate, passing your TFormatSettings to convert from a string to a date.
Call FormatDateTime overload that accepts a TFormatSettings when converting in the other direction.
Now, to the main thrust of your question. You should not be using strings at all for your dates and times in the scenario you describe. Use AsDateTime rather than AsString. If you happen to have a database column that does store a date/time as a string, then you'll should use the TFormatSettings based conversion functions to work around that design fault.
If you are absolutely dead set on doing this all with strings, and I cannot persuade you otherwise, then you need to use FormatSettings.ShortDateFormat from SysUtils to control your short date formatting.

What formats can I use for an xforms:input bound to a node of type xs:date?

I am looking at the <xforms:input> formatting documentation and am curious if it is at all possible to display the date as "3 Jul 2011". This should formatting very simple given the use of Java's SimpleDateFormat with the mask [d] [MMM] [yyyy]. The <xforms:input> documentation makes it seem possible to change the canonical format but only references Regex expressions.
Or am I restricted to the masks [M], [D] and [Y]?
You can choose pretty much any format you want when displaying a date or time with <xforms:output>. However, when capturing a date or time with <xforms:input>, Orbeon Forms limits you to just a few formats, as documented.
The reason for this is somewhat technical: for inputs, Orbeon Forms needs to be able to both format the date/time in the format you specify, and to parse it. And the parsing is implemented to accept as many reasonable date or time formats entered by the user. For instance, if you choose a [M]/[D]/[Y] format (typical in the US), you can enter 12/2/2011, but also 12/2 (skipping the year), or even 2 (skipping both the year and the month), or today, as well as several other formats.
The bottom line is that because of this "smart parsing", the <xforms:input> can only support a number of predefined formats. Additional formats can be added, but this requires Orbeon Forms itself to be changed to support those additional formats.

Getting substrings of the !today variable in Fitnesse

I'm writing a Fitnesse test for a web application. One of the items to test is a drop-down box, whose value is determined by the current date, in DD/MM/YYYY format.
I'd thought that using the !today variable in the Fitnesse suite might be a useful way of setting a variable, but I've run into the problem that Fitnesse expresses the date as (for example) 11 Mar, 2011, where I need 11/03/2011. I can get the date in numberic format using the -xml modifier, but I'm still left with a pretty huge string like 2011-03-11T05:51:22.
Is there a way of getting substrings of this, and then piping those into page variables, or am I barking up entirely the wrong tree here?
Thanks!
!today (MM/dd/yyyy) produces 09/17/2012. You can use any format codes you like. It uses the SimpleDateFormat class.
Well, it turns out not entirely the wrong tree :-)
For reference, the !today function has a few other methods, and you can use them to gather individual sections of the date as necessary:
!today (dd) - gives the day of the month, in numeric form
!today (MM) - gives the month of the year, in numeric form
!today (yyyy) - gives the year, in numeric form
There are a few others, but all I ended up using were these. Combine them as necessary, and Robert is your mother's brother, as it were...
This will get you the date you require in Test Cases written in Fitnesse Wiki
${=!today (ddMMyyyy)=}
The ! (Exclamation mark) is interpreted literally, so symbols like !today are not expanded. You can use a plain table:
|class name|
|!today (MM/dd/yyyy)|

Resources