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

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

Related

Convert the String Monday 5 October to date using Google Apps Script

I need to convert the date string of type WEEKDAY DATE MONTHNAME, Example: from "Monday 5 October" to date object.
I have tried with
Utilities.formatDate(new Date("Monday 5 October"), "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'")
How do I convert it, I am ok using V8 apps script engine
The Date constructor accepts timestamp strings formatted according to IETF-compliant RFC 2822 timestamps and ISO8601.
There are many ways to convert your string to date, but probably one of the simplest is appending the current year to your string, using getFullYear():
const source = "Monday 5 October";
const date = new Date(`${source} ${new Date().getFullYear()}`);
Reference:
Date() constructor
IETF-compliant RFC 2822 timestamps

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

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

Day from date 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

What is the precise definition of JDE's Julian Date format?

I am writing code to convert from a Gregorian date to a JDE (J.D.Edwards) Julian date.
Note: a JDE Julian date is different from the normal usage of the term Julian date.
As far as I can work out from Googling, the definition of a JDE Julian date is:
1000*(year-1900) + dayofyear
where year is the 4-digit year (e.g. 2009), and dayofyear is 1 for 1st January, and counts up all year to either 365 or 366 for 31st December (depending whether this is a leap year).
My question is this: are years before 1900 supported? If so, does the above formula still hold, or should it be this:
1000*(year-1900) - dayofyear
(note minus instead of plus.)
or something else?
Does anyone have a link to the official documentation for this date format?
The JDE Julian date consists of CYYDDD which is Century, Year, Day of year.
Century is zero for 20th e.g. 19XX and one for 21st e.g. 20XX.
The year is two digits.
So 101001 is 1 January 2001
As you can see this will not support dates before 1900.
See this Oracle page for a simple and official explanation: About the Julian Date Format
The "JDE Julian Date Converter" does return a negative value for:
1809/07/23 : -90635
As opposed to the classical Julian Date:
The Julian date for CE 1809 July 23 00:00:00.0 UT is
JD 2381986.50000
Here is a example of JD EDWARDS (AS/400 software) Julian Date, but that is not an "official" documentation and it does not seems to support dates before 1900...
Note: this "ACC: How to Convert Julian Days to Dates in Access and Back" does not support date before 1900 either... as it speaks about an "informal" Julian day, commonly used by government agencies and contractors.
The informal Julian day format used in this article is the ordinal day of a year (for example, Julian day 032 represents February 1st, or the 32nd day of the year).
Variations on informal Julian day formats include using a preceding two-digit year (for example 96032 for 2/1/96) and separating the year with a dash (for example 96-032).
Another, less popular, Julian day format uses a one digit year (for example 6-032). These additional formats do not uniquely identify the century or decade. You should carefully consider the consequences when using these formats; for example, the Julian day 00061 can be interpreted as 3/1/2000 or 3/2/1900.
Update: Sorry, JDE is probably something else. But for reference:
The JDE I know is different. From page 59 in the book
"Astronomical algorithms" (Jean Meeus, ISBN 0-943396-35-2):
"If the JD corresponds to an instant
measured in the scale of Dynamical
Time (or Ephemeris Time), the
expression Julian Ephemeris Day
(JDE) is generally used. (Not JED as
it is sometimes written. The 'E' is a
sort of index appended to 'JD')"
JD and JDE (for the same point in time) are close in value
as the difference UT and ET is on the order of minutes. E.g. ET-UT was 56.86 seconds in 1990 and -2.72 seconds in 1900.
There is also MJD (Modified Julian Day):
MJD = JD - 2400000.5
Zero point for MJD is 1858-11-17, 0h UT.
Note that JD as Julian date is a misnomer. It is
Julian day. The JD has nothing to do with the Julian
calendar. (This is in disagreement with the Wikipedia article, this
is from the author of the book mentioned above, Jean Meeus - a Belgian astronomer specializing in celestial mechanics.)
Maybe off from the question, you can convert in Excel using the following formula:
Convert Julian to Date in Excel
In Cell A2 place a Julian date, like 102324
in Cell B2 place this formula: (copy it in)
=DATE(YEAR("01/01/"&TEXT(1900+INT(A2/1000),0)),MONTH("01/01/"&TEXT(1900+INT(A2/1000),0)),DAY("01/01/"&TEXT(1900+INT(A2/1000),0)))+MOD(A2,1000)-1
The date 11/20/02 date will appear in cell B2
Convert Date to Julian in Excel
In Cell C2 copy this formula:
=(YEAR(B2)-2000+100)*1000+B2-DATE(YEAR(B2),"01","01")+1
This will convert B2 back to 102324
Save the below source code in a source member called JDEDATES. Use the runsqlstm on the first line to create the functions. You can then do things like
select jde2date(A1UPMJ), f.* from f00095 f
and see a real date.
Source:
--RUNSQLSTM SRCFILE(qtxtsrc) SRCMBR(JDEDATES) COMMIT(*NONE) NAMING(*SQL)
-- jde 2 date
create function QGPL/jde2date ( d decimal(7,0))
returns date
language sql
deterministic
contains sql
SET OPTION DATFMT=*ISO
BEGIN
if d=0 then return null;
else
return date(digits(decimal(d+1900000,7,0)));
end if;
end; -- date 2 jde
create function QGPL/date2jde ( d date)
returns decimal(7,0)
language sql
deterministic
contains sql
SET OPTION DATFMT=*ISO
BEGIN
if d is null then return 0;
else
return (YEAR(D)-1900)*1000+DAYOFYEAR(D);
end if;
end ;
Several years late to the party, but for other folks like me that find yourselves working with legacy systems like this, I hope some of my java snippets can help. I'm leveraging the fact that you can convert this CYYDDD format into yyyyDDD format and parse based on that.
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Calendar;
import java.util.SimpleDateFormat;
String jdeJulianDate = "099365"; //Testing with December 31, 1999
// Compile what the year number is
int centIndex = Integer.parseInt(jdeJulianDate.substring(0,1));
int yearIndex = Integer.parseInt(jdeJulianDate.substring(1,3));
int yearNumber = 1900 + (100 * centIndex) + yearIndex;
// Put the year number together with date ordinal to get yyyyDDD format
String fullDate = String.valueOf(yearNumber) + jdeJulianDate.substring(3,6);
// Date parsing, so need to wrap in try/catch block
try {
Date dt = new SimpleDateFormat("yyyyDDD").parse(fullDate);
// Validate it parses to a date in the same year...
Calendar cal = new GregorianCalendar();
cal.setTime(dt);
if (cal.get(Calendar.YEAR) != yearNumber) {
// Cases happen where things like 121366 (should be invalid) get parsed, yielding 2022-01-01.
// Throw exception or what-not here.
}
}
catch (Exception e) {
// Date parsing error handling here
}
A sample of VBA code to convert back and forth between JDE Julian Date and Gregorian:
Public Const Epoch = 1900
Public Const JDateMultiplier = 1000
Public Const FirstJan = "01/01/"
Public Function Julian2Date(ByVal vDate As Long) As Date
Dim Year As Long
Dim Days As Long
Dim SeedDate As Date
' Day Number
Days = vDate - (Int(vDate / JDateMultiplier) * JDateMultiplier) - 1
' Calendar Year
Year = ((vDate - Days) / JDateMultiplier) + Epoch
' First Day of Calendar Year
SeedDate = CDate(FirstJan + CStr(Year))
' Add Number of Days to First Day in Calendar Year
Julian2Date = DateAdd("d", Days, SeedDate)
End Function
Public Function Date2Julian(ByVal vDate As Date) As Long
Dim JYear As String
Dim BeginDate As Date
Dim JDays As Long
' Calendar Year
JYear = Format(Year(vDate), "0000")
' First Day of Calendar Year
BeginDate = CDate(FirstJan + JYear)
' Day Number
JDays = DateDiff("d", BeginDate, vDate) + 1
' Add Number of Days to Year Number
Date2Julian = ((CLng(JYear) - Epoch) * JDateMultiplier) + JDays
End Function
I have tried to make it as clear and simple as possible, and to this end I have intentionally left out any error trapping. However, you should be able to add the code to a VBA module and call them directly from your own code.
I also include some useful snippets of T-SQL:
Todays Date as JDE Julian Date:
(datepart(yy,getdate())-1900) * 1000 + datepart(dy, getdate())
Convert JDE Julian Date to Gregorian (DD/MM/YYYY), replace XXXXXX with the column name containing the JDE Julian Date:
convert (varchar, dateadd (day,convert (int, right(XXXXXX,3)) - 1, convert (datetime, ('1/1/' + convert ( varchar, (cast(left(right(XXXXXX+1000000,6),3) as varchar) + 1900))))),103)
If you require a different Gregorian format, replace the 103 value (right at the end) with the applicable value found here: https://msdn.microsoft.com/en-us/library/ms187928.aspx
I have an easy way for C using time now and epoch 1970, 01, 01 midnight if anybody is interested.
But this is for Julian Day Numbers which is not the same as JDE but they are similar in respect to using math to compute days and I'm sure this idea could be adapted for JDE. Sometimes people just confuse the two like I do. Sorry. But still this is an example of using a time reference which should always be done and since most computers use this it would be just as easy for us not to get too bogged down in dates and just use days before or after this epoch.
Since JDE is now owned by Oracle, they also now support Julian_Day. see:
https://docs.oracle.com/javase/8/docs/api/java/time/temporal/JulianFields.html
#include <stdio.h>
#include <time.h>
#define EPOCH (double) 2440587.5 /* Julian Day number for Jan. 01, 1970 midnight */
int main ()
{
double days = time(0)/86400.0;
printf ("%f days since January 1, 1970\n", days);
printf ("%f\n", days + EPOCH);
return 0;
}
Wow, there's a lot of complicated code in some of these answers just to convert to and from JDE julian dates. There are simple ways in Excel and VBA to get there.
FROM JULIAN
Excel (assuming julian date is in A1):
=DATE(1900+LEFT(A1,LEN(A1)-3),1,RIGHT(A1,3))
VBA (from julian date, j, stored as String):
d = DateSerial(1900 + Left$(j, Len(j) - 3), 1, Right$(j, 3))
VBA (from julian date, j, stored as Long):
d = DateSerial(1900 + Left$(j, Len(CStr(j)) - 3), 1, Right$(j, 3))
TO JULIAN
Excel (assuming date is in A1):
=(YEAR(A1)-1900)*1000+A1-DATE(YEAR(A1),1,0)
VBA (to a Long, j):
j = (Year(d) - 1900) * 1000 + DatePart("y", d)