DateTimeParseException on Java 11 but works on Java 10 - java-time

The following testcase runs perfectly under Java 10:
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
class Test
{
public static void main (String[] args) throws java.lang.Exception
{
DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder().
appendPattern("EEE, dd MMM yyyy HH:mm:ss zzz").
toFormatter();
Instant result = dateFormatter.parse("Sat, 29 Sep 2018 20:49:02 GMT", Instant::from);
System.out.println("Result: " + result);
}
}
but under Java 11 I get:
Exception in thread "main" java.time.format.DateTimeParseException: Text 'Sat, 29 Sep 2018 20:49:02 GMT' could not be parsed at index 0
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
at Test.main(Test.java:13)
What's going on?
UPDATE: Replacing toFormatter() with toFormatter(Locale.US) fixes the problem. I am guessing this issue is related to https://bugs.openjdk.java.net/browse/JDK-8206980. This issue is marked as fixed in Java 11 build 23 but I am running
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)
Shouldn't this be fixed in this version?
UPDATE2: If you are unable to reproduce the problem, try replacing toFormatter() with toFormatter(Locale.CANADA).

DateTimeFormatter.RFC_1123_DATE_TIME
Your date-time string is in RFC 822/RFC 1123 format. Instead of building your own formatter use the built-in DateTimeFormatter.RFC_1123_DATE_TIME:
Instant result = DateTimeFormatter.RFC_1123_DATE_TIME
.parse("Sat, 29 Sep 2018 20:49:02 GMT", Instant::from);
System.out.println("Result: " + result);
Output is:
Result: 2018-09-29T20:49:02Z
This RFC 1123 formatter is always in English, as required by the RFC specification. I even tried setting my default locale to Locale.CANADA_FRENCH, and the code still worked.
What went wrong in your code?
In Java 11 Java expects that the abbreviations for day of week and for month are written with a dot in Locale.CANADA: Sat. and Sep. rather than Sat and Sep. In Java 10 they are expected without dots, so here parsing works. The difference probably lies in different versions of CLDR data and can hardly be considered a bug in any of the mentioned Java versions. Since Java 9 CLDR has been the default locale data in Java — including what day and month abbreviations look like in different locales.
Demonstration: Using your formatter, but modifying it to use Locale.CANADA as you said:
DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder().
appendPattern("EEE, dd MMM yyyy HH:mm:ss zzz").
toFormatter(Locale.CANADA);
System.out.println("Sample: " + ZonedDateTime.now(ZoneId.of("America/Toronto"))
.format(dateFormatter));
Running on Java 10.0.2 this printed no dots:
Sample: Sun, 30 Sep 2018 10:39:28 EDT
And on Java 11 build 11+28:
Sample: Sun., 30 Sep. 2018 10:50:29 EDT
So I believe that the behaviour has nothing to do with the bug report you linked to.
Links
DateTimeFormatter.RFC_1123_DATE_TIME documentation
CLDR - Unicode Common Locale Data Repository home page
JDK Bug System: DateTimeFormatter throws parsing a valid string depending on the locale

Related

In Conky, how do I convert from Unix time to hours and minutes? (HH:MM)

Given a Unixtime such as 1551996855 (Thu, 07 Mar 2019 22:14:15 +0000), how can convert and extract just HH:MM, (22:14)?
you could use date for the conversion and specify +%H:%M as the format:
date -d #$"1551996855" +%H:%M
note: the option to use with date will be different than -d if you are not on a Linux system (which uses date from GNU coreutils).. so YMMV

How do I get yesterday date in Freeswitch?

In Freeswitch dialplan, I know I can get today date using ${strftime(%Y%m%d}, but how do I get yesterday date correctly?
I can do ${strftime(%Y%m)}${expr(${strftime(%d}-1)}, but what about yesterday date of Jan, 1st, 2017?
Thanks for all your helps.
var.xml
<X-PRE-PROCESS cmd="exec-set" data="yesterday=date -d 'yesterday' +'%b %d %Y'">
fs_cli
freeswitch#host> eval $${yesterday}
Nov 16 2017

Convert "Thu Sep 22 3:50 2016" to "2016-09-22" in Solaris, without GNU date

Could someone please suggest a simple and short approach to convert "Thu Sep 22 3:50 2016" to "2016-09-22" in Solaris, through a shell script?
I do not have GNU date available on Solaris as discussed in below post:
Convert date String to number on Solaris shell script gives No such file or directory
I need to query an sql server db, where date is saved in the format, "2016-09-06", hence I need to convert it
Actually, you do have GNU date available but here is anyway one way to achieve this by scripting:
#!/bin/ksh
a="Thu Sep 22 3:50 2016"
echo $a | nawk '
BEGIN {
m=1
m2m["Jan"]=m++;
m2m["Feb"]=m++;
m2m["Mar"]=m++;
m2m["Apr"]=m++;
m2m["May"]=m++;
m2m["Jun"]=m++;
m2m["Jul"]=m++;
m2m["Aug"]=m++;
m2m["Sep"]=m++;
m2m["Oct"]=m++;
m2m["Nov"]=m++;
m2m["Dec"]=m++;
}
{
printf("%s-%02d-%02d\n",$5,m2m[$2],$3)
}'
output:
2016-09-22
Why not use Oracle's sysdate?
select * from your_table where saved_date >= to_char(sysdate,'yyyy-MM-dd')

Setting Date format for autoprop 'DATE' in SVN

I have some files that use the autoproperty $Date of SVN.
When some colleagues in France do a checkout of the repository, the date is in French. When they do the verification of checksum, these files are KO because of this difference of format for the date.
Note: we are using Windows and our client of choice is TortoiseSVN but are open to use command line clients.
Question 1: Is there any way to force the format for the date during the checkout?
We tried the following:
Setting "English" in Tortoise SVN
Setting environment variable LANG to EN_US and doing a checkout with both TortoiseSVN and svn commandline
None of these solutions is working.
Question 2: Would the time zone impact the date in the header as well?
Thanks
NB: This is the header of our source code, for what it matters.
/*==============================================================================================
* FILENAME : Source.h
* VERSION : $Revision: 85911 $
* MODIFICATION DATE : $Date: 2015-06-12 18:26:22 +0800 (Fri, 12 Jun 2015) $
*============================================================================================*/
A1: I don't know, how to manipulate locale-setting in Windows in easy and automated style - inspired by this old answer in Subversion maillist - (better to ask it SU) and can suggest now only dirty hack: import reg-files for FR and EN locales before and after checkout (how to prepare: switch to FR in Control Panel, save Current Control Set part of registry, return to EN, save CCS again, leave in .reg only mutable part), checkout in bat-file only (change locale around checkout)
A2: Sad, but yes
$Date: 2015-06-19 19:45:22 +0500 (Пт, 19 июн 2015) $
inserts not only language-specific date (trailing part), but also TZ of client
1.8.*-specific solution: you can create and use replacement for $Date keyword, which use UTC-time instead of local (as $Id do for time-part now) with %d variable it it
>svn pl -v file.txt
Properties on 'file.txt':
svn:keywords
Author Date Id Revision URL Header IntDate=%d
and IntDate will expand location-independent
$IntDate: 2015-06-19 14:45:22Z $

perl DateTime incorrect timezone offset

I have several servers running under centos 6.3 and I faced issue that perl module DateTime treats Europe/Moscow timezone as UTC+3
[ulan#rt-virtual ~]$ perl -MDateTime -e 'print DateTime->now()->set_time_zone("Europe/Moscow"), "\n";'
2013-12-19T11:11:38
but in fact it is UTC+4 and system tools like zdump or date work correctly
[ulan#rt-virtual ~]$ zdump Europe/Moscow
Europe/Moscow Thu Dec 19 12:11:47 2013 MSK
I updated tzdata and DateTime module but it didn't help.
How can I amend this?
Thanks.
Well, DateTime module is doing its magic by following the rules specified in the TimeZone modules specific for each timezone. For Europe/Moscow, the module's is DateTime::TimeZone::Europe::Moscow. The problem is all the files are generated automatically corresponding to the rules existing when a specific version of DateTime module is released.
In this case one very important change - Russia's stopping following DST routines in 2011 - wasn't obviously reflected in that file. So updating - either the whole module or only the relevant TimeZone part - should have fixed the issue.
You can use your systems tzfile(5), using DateTime::TimeZone::Tzfile. Not only does it perform better than DateTime::TimeZone it also removes the need to have redundant data that needs to be in sync.
$tz = DateTime::TimeZone::Tzfile->new('/etc/localtime');
$dt = DateTime->now(time_zone => $tz);