Day from date Scala - scala

I'd like to get the day from a date object as an integer. This is my code so far.
val dateString = "2015-11-24 23:23:09"
val format = new java.text.SimpleDateFormat("yyyy-MM-dd H:m:s")
val date = format.parse(dateString)
print(date) # this gives Tue Nov 24 23:23:09 CST 2015
Now, from date, I want to get the day of the month as an integer. How do I do that?
Thanks.

Just use the Java Calendar class (although I would recommend moving over to the Joda library if you are doing much serious work with dates/times):
val cal = Calendar.getInstance()
cal.setTime(date)
val dayOfMonth = cal.get(Calendar.DAY_OF_MONTH)

tl;dr
LocalDateTime.parse(
"2015-11-24 23:23:09".replace( " " , "T" )
).getDayOfMonth()
java.time
The modern approach uses the java.time classes.
Using Java syntax here as I don't know Scala. Note that java.time uses immutable objects.
Convert your string to comply with ISO 8601 standard format with a T in the middle.
String input = "2015-11-24 23:23:09".replace( " " , "T" ) ;
Parse as an LocalDateTime as your input lacks any time zone or offset-from-UTC.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
Interrogate for the day of month.
int dom = ldt.getDayOfMonth() ;

Using Joda,
org.joda.time.DateTime.now().getDayOfMonth()
or equivalently,
import java.util.Date
new org.joda.time.DateTime(new Date()).getDayOfMonth

Related

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());

Year-Week-Day in java.time?

Is there support in the java.time classes, or its extension ThreeTen-Extra, for a week dates, specifically a Year-Week-Day such as 2009-W53-7 which is Sunday 3 January 2010.
As for the year-week without the day-of-week:
My Answer to the Question, java get week of year for given a date, explains using IsoFields to handle the year-week.
The ThreeTen-Extra project that extends the java.time classes offers the YearWeek class.
But how to represent the day-of-week as well?
See the IsoFields class, which allows the week-based year and week of week-based year to be queried. There is also a dedicated formatter ISO_WEEK_DATE.
The DayOfWeek enum tells you the number of the day-of-week, 1-7 for Monday to Sunday. Call LocalDate::getDayOfWeek and then DayOfWeek::getValue.
LocalDate ld = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;
2016-12-07
int weekOfWeekBasedYear = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int yearOfWeekBasedYear = ld.get( IsoFields.WEEK_BASED_YEAR ) ;
int dayOfWeek = ld.getDayOfWeek().getValue();
Use these parts to build strings in the standard ISO 8601 week date formats.
String yearWeek = yearOfWeekBasedYear + "-W" + String.format( "%02d", weekOfWeekBasedYear ) ;
2016-W49
String yearWeekDay = yearWeek + "-" + dayOfWeek ;
2016-W49-3
Or, let the predefined DateTimeFormatter.ISO_WEEK_DATE do the work.
String ywd = ld.format( DateTimeFormatter.ISO_WEEK_DATE );
2016-W49-3
That same formatter can parse such standard strings.
String input = "2016-W49-3" ;
LocalDate ldParsed = LocalDate.parse( input , DateTimeFormatter.ISO_WEEK_DATE ) ;
2016-12-07

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')

How to set client specific timezone and 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.