I'm trying to parse a string that contains a DateTime
def parseDateTime(str : String) : DateTime = {
//need to parse date time of this format
//2015-05-22T05:10:00.305308666Z
DateTime.parse(str,DateTimeFormat.forPattern(dateTimePattern))
}
def dateTimePattern = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSZ"
and here is my test case trying to parse the date time
"MarshallerUtil" must "parse a date time correctly from blockcypher" in {
val str = "2015-05-22T05:10:00.305308666Z"
val dateTime = parseDateTime(str)
dateTime.getYear must be (2015)
dateTime.getMonthOfYear must be (DateTimeConstants.MAY)
dateTime.getDayOfMonth must be (22)
dateTime.getHourOfDay must be (5)
dateTime.getMinuteOfHour must be (10)
}
and it fails to get the correct hour
[info] - must parse a date time correctly from blockcypher *** FAILED ***
[info] 0 was not equal to 5 (MarshallerUtilTest.scala:17)
What is incorrect on my pattern?
That's because it parses the date time as UTC and when you invoke the getHourOfDay, it returns the time unit with local timezone. For example the same program printed '10' here, because my local timezone is '+05:30' and so, 05:10 and a 05:30 is 10:40. I hope this helps.
Update:
Z is a placeholder/matcher that is used in the date time pattern to match a timezone. A timezone has the form '+HH:mm' or '-HH:mm', for example '+05:30' means that the timezone is 5 hours and 30 mins ahead of the UTC time.
Related
I have the following datetime from a database: 2022-10-02T23:10:24.736Z I want to compare it to a datetime now and get the difference in second. Basically I have the code for it, but im not able to convert the datetime.now to the mentioned format. It tells me it has a difference of 122 minutes but it should only be 2 minutes..
DateTime datenow = DateTime.now();
DateTime dateFormDatabase = DateTime.parse(widget.data[widget.currIndex-1]["roundEnd"]);
print(datenow); // <---- 2022-10-01 23:22:45.522687
print(dateFormDatabase); // <--- 2022-10-01 23:25:24.736Z
var diff = dateFormDatabase.difference(datenow);
print(diff.inMinutes); // <--- 122 but it should be 2minutes
The returned difference is correct. You are probably looking at different timezones here. DateTime.now() returns the current date and time in your local timezone. The parsed date from your database seems to be coming in as UTC. Notice the "Z" at the end here: 2022-10-01 23:25:24.736Z.
If you want to visually compare them you could convert either of those to UTC/local with toUtc or toLocal
Let's say I have this Model:
type alias Model =
{ currentDate : String
, yesterdayDate : String
}
The CurrentDate I got from Html input type date (Date Picker) is in format YYYY-MM-DD
Html Form
input [ name "date", type_ "date", onInput UpdateDate ] []
Update.elm
UpdateDate date ->
let
-- Get Yesterday Date function here
in
( { model | currentDate = date, yesterdayDate = "" }, Cmd.none )
In this situation , how can i get yesterday Date in String ?
My idea is parse the day into INT and using subtraction method to get Yesterday day but I cannot find any way to do it... Any help is appreciate.
Convert the string date to Posix, convert the Posix to milliseconds since epoch, subtract the amount of milliseconds in a day, convert the resulting milliseconds back to Posix and the Posix to an ISO8601 string. Take the first 10 characters from that string.
module Main exposing (main)
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
import Iso8601
import Time exposing (Posix)
sampleDate =
"2020-05-01"
subtractDays : Int -> Posix -> Posix
subtractDays days time =
(Time.posixToMillis time - (days * 24 * 60 * 60 * 1000))
|> Time.millisToPosix
subtractDaysFromIsoDate : Int -> String -> String
subtractDaysFromIsoDate days date =
Iso8601.toTime date
|> Result.map (subtractDays days >> Iso8601.fromTime >> String.left 10)
|> Result.withDefault date
main =
text <| subtractDaysFromIsoDate 1 sampleDate
Note that in this implementation if the string is not a valid date it will just be returned unmodified rather than fail. You might want to capture that this operation can fail.
As you can trust that you get a valid string format from html and are aware of the date package, you can split the date string into 3 strings, convert each into an integer and then construct today and yesterday as a Date value.
Questions you should ask yourself:
Do you really want to store the date as a String? The Date type might be more useful if you want to do something else then just display the string value.
And do you really want to store both today and yesterday? The latter can be easily computed when needed.
Example for string splitting:
case
String.split "-" date
|> List.map String.toInt
of
[ Just year, Just monthInt, Just day ] ->
-- convert monthInt to `Month`
-- construct current date
-- add -1 `Day`
Debug.todo "todo" 2
_ ->
Debug.todo "invalid date format" date
I am trying to convert a long utc value into "yyyy-MM-dd HH:mm:ss" formatted pattern. I am expecting my data to be converted on 24 hours range scale and in GMT. My code passes all the test cases, I push the data into database using the jar that is newly built with this code -
dbRecord("order_dt_utc") = if (orderTs.isDefined) Some(new DateTime(orderTs.get, DateTimeZone.UTC).toString("yyyy-MM-dd HH:mm:ss")) else None
and now, when I query my database, I find that the data is still converting on 12 hours range. The query -
SELECT order_id, order_dt, order_dt_utc, order_ts_utc, from_unixtime(order_ts_utc/1000) FROM order_items where order_dt >= '2018-08-01' AND order_dt <= '2018-08-02' ORDER BY order_dt_utc LIMIT 1000;
And you can see the the values are not matching in the columns from_unixtime(order_ts_utc/1000) and order_dt_utc -
I am not able to figure the reason for this behaviour.
To convert Time Zone use the function first:
CONVERT_TZ (dateobj, oldtz, newtz)
After that use the date_format function:
date_format(from_unixtime(order_ts_utc), '%Y-%m-%d %H:%i:%s');
to format your time to 00-23 format.
I have a timestamp like "1461819600". The I execute this code in a distributed environment as val campaign_startdate_year: String = Utils.getYear(campaign_startdate_timestamp).toString
The problem is that I always get the same year 1970. Which might be the reason of it?
import com.github.nscala_time.time.Imports._
def getYear(timestamp: Any): Int = {
var dt = 2017
if (!timestamp.toString.isEmpty)
{
dt = new DateTime(timestamp.toString.toLong).getYear // toLong should be multiplied by 1000 to get millisecond value
}
dt
}
The same issue occurs when I want to get a day of a month. I get 17 instead of 28.
def getDay(timestamp: Any): Int = {
var dt = 1
if (!timestamp.toString.isEmpty)
{
dt = new DateTime(timestamp.toString.toLong).getDayOfYear
}
dt
}
The timestamp you have is a number of seconds since 01-01-1970, 00:00:00 UTC.
Java (and Scala) usually use timestamps that are a number of milliseconds since 01-01-1970, 00:00:00 UTC.
In other words, you need to multiply the number with 1000.
The timestamp that you have seems to be in seconds since the epoch (i.e. a Unix timestamp). Java time utilities expect the timestamp to be in milliseconds.
Just multiply that value by 1000 and you should get the expected results.
You can rely on either on spark sql function which have some date utilities (get year/month/day, add day/month) or you can use JodaTime library to have more control over Date and DateTime, like in my answer here: How to replace in values in spark dataframes after recalculations?
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')