How to set client specific timezone and date - date

pardon me if it seems to be a duplicate question.
I have seen many posts already on this topic. However after trying many examples could not find the solution to my problem.
I tried this code
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd yyyy", Locale.ENGLISH )
Date newDate = sdf.parse(sdf.format( new Date( dateTimeString ) ) )
However the second line of code always converts the date to the server specific date and timezone which i don't want. I also tried the following
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss zzz", Locale.ENGLISH )
log.info "+++++++++++++++++hidden date ++++++++ " + params.hiddenGameDateTime.substring(35, 38)
log.info "x = " + sdf.format( new Date ( params.hiddenGameDateTime ))
String tzone = params.hiddenGameDateTime.substring(35, 38)
sdf.setTimeZone( TimeZone.getTimeZone( tzone ) )
log.info "Timezone = " + sdf.getTimeZone().getDisplayName()
Please note that
sdf.format( new Date( dateTimeString ) )
gives me the desired result, however it gives me the string value of the date and the actual value to be stored in database is of the Data type date which can't hold the string value.
the value for date and time in my case gets converted to PST date and time. how can i avoid this. The user input date with timezone should be stored in the database as it is with no change in date and timezone.

An observation: The constructor new Date( dateTimeString ) is deprecated. A better replacement would be something like that:
SimpleDateFormat sdfOriginal = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
Date d = sdfOriginal.parse(dateTimeString);
Furthermore: An expression like sdf.parse(sdf.format(...)) using the same format object does not make much sense.
But most important, your statement "the second line of code always converts the date to the server specific date and timezone" seems to be based on test output like:
System.out.println(newDate);
This implicitly uses toString() which is based on jvm default time zone, in your case the server time zone. But keep in mind, the internal state of j.u.Date does not reference any time zone. A Date is just a container for a long, namely the seconds since 1970-01-01T00:00:00Z in UTC time zone, that is a global time.
Additional remark:
If you need the client time zone (in a scenario with multiple users in different time zones) to create user-specific formatted date strings, then you indeed need to store the time zone preference of every user in the database, so you can use this information for output in an expression like:
SimpleDateFormat sdf = new SimpleDateFormat("{pattern}";
sdf.setTimeZone(TimeZone.getTimeZone("{user-preference-time-zone}");
String userOutput = sdf.format(date);

Date is always jvm timezone specific. You need to normalize it to standard time and store it in DB to cater with different timezone servers.

Related

talend format yyyy-MM-dd'T'HH:mm:ss.SSSz to yyyy-mm-dd HH:mm:ss

I am trying to change the date format in txmlmap component but its not working
i want change date format
from yyyy-MM-dd'T'HH:mm:ss.SSSz to yyyy-mm-dd HH:mm:ss
expected output:- yyyy-mm-dd HH:mm:ss
You can parse your string to a date using your source pattern and then format that date to a string using your target pattern:
TalendDate.formatDate("yyyy-mm-dd HH:mm:ss", TalendDate.parseDate("yyyy-MM-dd'T'HH:mm:ss.SSSz", myDateString))
In almost all coding languages format is text, while date is a double. That means you must first make a date of the first expression, before setting the new format of that date. But in Your case the 'T' is some kind of special format that need to be replaced with a blanck space. I have no idea about what it would look like in talend but in VB it would look like this:
' from yyyy-MM-dd'T'HH:mm:ss.SSSz to yyyy-mm-dd HH:mm:ss
DateTxt = "2022-12-01'T'22:45:10"
DateTxt = Replace(DateTxt, "'T'", " ")
MyDate = CDate(DateTxt)
MsgBox Format(MyDate, "yyyy-mm-dd HH:mm:ss")

Java 8 LocalDateTime has different results

I am trying to update some code to use Java 8's feature for parsing multiple date formats. my local time on my box is set to UTC-11.
the below code works when using the SimpleDateformat.
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date correctDate = dateFormat.parse("2018-09-6T03:28:59.039-04:00");
//Gives me correct date
System.println( correctDate);//Wed Sep 5th 20:28:59 GMT-11:00 2018
I am trying to update this code to give the same date as above with the DateTimeFormatter in Java 8 , so i can handle another date format..
DateTimeFormattter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS]XXX");
LocalDateTime updateDate = LocalDateTime.parse( "2018-09-6T03:28:59.039-04:00", dtf);
//shows the wrong date of 2018-09-06 03:28:59.039.
System.out.println( updateDate.toString() );// 2018-09-06 03:28:59.039
[solved]
I was able to fix this by using ZonedDateTime.
ZonedDateTime zdt = ZonedDateTime.parse("2018-09-6T03:28:59.039-04:00");
zonedDateTime = zdt.withZoneSameInstance(ZoneId.of("GMT"));
Date correctDate = Date.from( zonedDateTime.toInstance());
//correctDate is what i wanted Wed Sep 5th 20:28:59 GMT-11:00 2018
As soon as you parse your date string into a LocalDateTime the zone offset is lost because LocalDateTime does not hold any time zone or offset information.
When you format the LocalDateTime to a string again, you'll only have the time as it was parsed without offset.
The Documentation of LocalDateTime clearly explains this:
This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.
You should consider using OffsetDateTime or ZonedDateTime.
Solved, using OffsetDateTime as suggested in the accepted 'Answer':
OffsetDateTime odt = OffsetDateTime.parse("2018-09-6T03:28:59.039-04:00");
Date correctDate = Date.from( odt.toInstant());

set date default ion-datetime Ionic v-2

I have problem i try set the default date is today end disable day passed.
But when i set the default date is today i must convert date to string. So i can't calculator this.
Some body help me set the default date is today and calculator date. Thanks for reading my topic!
This is my code:
this.startDate = new Date().toISOString();
this.minDate = new Date().toISOString();
<ion-datetime
displayFormat="MMM DD, YYYY HH:mm"
[min]="minDate"
[(ngModel)]="startDate"
>
</ion-datetime>
From ionicv2 docs
https://ionicframework.com/docs/api/components/datetime/DateTime/
Ionic uses the ISO 8601 datetime format for its value. The value is
simply a string, rather than using JavaScript's Date object.
Additionally, when using the ISO datetime format, it makes it easier
to serialize and pass within JSON objects, and sending databases a
standardized format which it can be easily parsed if need be.
So, you can get the ISO string date by
startDate: String = new Date().toISOString();
and use it in the view like so
<ion-datetime
displayFormat="MMM DD, YYYY HH:mm"
[(ngModel)]="startDate"
>
If you want to disable backdated date, you can try this
min="2016-10-31"
and also you can specify the maxDate by
max="2020-12-12"
in your ion-datetime directive

Using Groovy - Add text to a returned date based on the time

I am running this groovy script:
def sdf = new java.text.SimpleDateFormat("yyyy-MM-dd kk:mm:ss")
return sdf.format( new Date())
and it returns = 2016-03-23 16:54:39
Which is fine however at the end of the returned value I want to add a space and either AM or PM depending on the what time it is (AM or PM time) as per the below:
AM time returns = 2016-03-23 11:54:39 AM
PM time returns = 2016-03-23 16:54:39 PM
Any ideas?
If you want to append AM / PM you can append an 'a' (Am/pm marker) at the end of the date formatter pattern:
new java.text.SimpleDateFormat("yyyy-MM-dd kk:mm:ss a").format(new Date())
This will yield:
2016-03-23 18:05:20 PM
See the Java documentation for the exact details of SimpleDateFormat.
It's even easier with groovy, as Date had a format method;
println new Date().format('yyyy-MM-dd HH:mm:ss a')
java.time
The Date and SimpleTextFormat classes are now outmoded by the java.time framework built into Java 8 and later.
An Instant is a moment on the timeline in UTC with up to nanosecond resolution.
The code in this Answer is Java, as I do not know Groovy syntax.
Instant instant = Instant.now();
Apply a time zone to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Define your formatting pattern. These codes in DateTimeFormatter are similar to SimpleDateFormat but not exactly the same. Study the class doc.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "yyyy-MM-dd kk:mm:ss" );
Be aware that the kk used in that particular pattern means 1-24 used for hours of the day instead of 0-23 (hh).
Generate a String as a textual representation of your date-time object.
String output = zdt.format( formatter );

How to create new Date in Groovy at specific date and time

I wonder if there is other way how to create new Date in Groovy at specific date and time than parse it from String with Date.parse method. Can I get complete list of Date creation in Groovy?
You can use the existing Java methods to create a date:
// takes the date encoded as milliseconds since midnight, January 1, 1970 UTC
def mydate = new Date(System.currentTimeMillis())
// create from an existing Calendar object
def mydate = new GregorianCalendar(2014, Calendar.APRIL, 3, 1, 23, 45).time
Groovy also provides some streamlined extensions for creating Dates. Date.parse() and Date.parseToStringDate() parse it from a String. The Date.copyWith() method builds a date from a map. You can use them like this:
// uses the format strings from Java's SimpleDateFormat
def mydate = Date.parse("yyyy-MM-dd hh:mm:ss", "2014-04-03 1:23:45")
// uses a format equivalent to EEE MMM dd HH:mm:ss zzz yyyy
def mydate = Date.parseToStringDate("Thu Apr 03 01:23:45 UTC 2014")
def mydate = new Date().copyWith(
year: 2014,
month: Calendar.APRIL,
dayOfMonth: 3,
hourOfDay: 1,
minute: 23,
second: 45)
The other answers are outdated as of Java 8 and later. The old legacy date-time classes such as java.util.Date/.Calendar/.GregorianCalendar have proven to be poorly designed, confusing, and troublesome.
java.time
The java.time framework supplants those old classes.
Groovy can use these classes of course. I do not know the Groovy syntax, but it should be easy to adapt this simple Java example.
LocalDate/LocalTime
The LocalDate and LocalTime classes have no concept of time zone. So they do not represent actual moments on the timeline.
LocalDate localDate = LocalDate( 2016 , Month.JANUARY , 2 ); // year, month, date.
LocalTime localTime = LocalTime( 12 , 30 , 0 , 0 ); // hour, minute, second, nanosecond.
ZonedDateTime
Apply a time zone (ZoneId) to get a ZonedDateTime. Use a proper time zone name, never the 3-4 zone abbreviations commonly seen.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.of( localDate , localTime , zoneId );
Instant
You should avoid the old date-time classes. But if required, you can convert. An Instant is the java.time class to represent a moment on the timeline in UTC with a resolution of nanoseconds. Look for new methods on the old java.util.Date class for converting to/from an Instant. We can extract the needed Instant object from our ZonedDateTime.
Nanosecond vs Millisecond
Note that converting from java.time involves data loss! The java.time classes support nanosecond resolution (up to 9 digits of decimal place on fractional second) while the old java.util.Date supports only milliseconds (up to 3 decimal places). Any 4th to 9th digit of fractional second is truncated. For example, 2016-04-28T02:05:05.123456789 is truncated to 2016-04-28T02:05:05.123.
Instant instant = zdt.toInstant();
java.util.Date utilDate = java.util.Date.from( instant );
Going the other direction, from java.util.Date to Instant. The 4th to 9th decimal place of fractional second will be zeros, the 1st-3rd for any milliseconds.
Instant instant = utilDate.toInstant();
Groovy is good.
new Date(2016-1900, 7, 16, 20, 32, 25)
Tue Aug 16 20:32:25 PDT 2016
Note that the year must be massaged, but you can create a new Java Date representing any second you want.
You can see more Groovy Goodness at http://mrhaki.blogspot.com/2009/08/groovy-goodness-working-with-dates.html
As far as I know there's no other way. You can also pass exact time in millis to constructor of Date class but first You need to get the time in millis.
Maybe this link will be helpful.
Or this code snippet:
def calendar = new GregorianCalendar(2011,1,7,15,7,23)
def date = calendar.getTime()
println date
You can get current date using Date() and format it the way you want using:
/*
y: year
m: month
d: day
h: hour
m: minute
*/
Date().format('yyyy-MM-dd hh-mm')
Date().format('yy/mm/dd hh')
The return type is a string.
LocalDateTime.now().format('yyyy-MM-dd hh-mm')