Groovy: Time in ISO 8601 format - datetime

How to get the current time and 15 min ago time in iso 8601 format (YYYY-MM-DDTHH:mm:ss) in groovy?

You can use java time's Instant and the toString() format
import java.time.*
def now = Instant.now()
def fifteenAgo = now.minus(Duration.ofMinutes(15))
println "Now is ${now} and 15 mins ago was ${fifteenAgo}"
Prints:
Now is 2020-06-30T19:53:17.445039Z and 15 mins ago was 2020-06-30T19:38:17.445039Z

You can formast the date in any way you want in Groovy, by doing e.g.
println new Date().format("yyyy-MM-dd HH.mm.ss.SSSSS Z")
Then, you can do calculations on the date, like this:
new Date(System.currentTimeMillis()-91*60*1000)
which will minus 91 minutes (91min * 60sec * 1000ms).
Then you can put the statements together, which is why Groovy is great:
def a = new Date(System.currentTimeMillis()-91*60*1000).format("YYYY-MM-DD")
And so you can get the half before the T. And the half after the T:
def b = new Date(System.currentTimeMillis()-91*60*1000).format("HH:mm:ss")
And then concatenate them with a T:
println "91 minutes ago in iso 8601 format is: ${a}T${b}"
There are other ways of doing it, like with TimeCategory.minus, but this is a good illustration. I used 91 minutes, but you can adapt it to your own requirtement.

Related

How do I show time in ASP.NET?

I have a label in my asp.net web site that will shows the time. I want the output like here. in the morning like this: 08:26 and after 12 am,it shows 15:28
My code does not work. It only supports the first part.
DateTime tim = DateTime.Now;
int hh = p.GetHour(tim);
int mm = p.GetMinute(tim);
Label7.Text = DateTime.Now.ToString("hh:mm");
According to the Custom date and time format strings docs page - you can see:
"hh" The hour, using a 12-hour clock from 01 to 12.
"HH" The hour, using a 24-hour clock from 00 to 23.
So in your case - just use the capitalized HH for your formatting:
Label7.Text = DateTime.Now.ToString("HH:mm");
and you should get what you're looking for.

Why is the difference of two datetime.now() objects not close to 0?

I am confused about the output of the following code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import datetime
import pytz
local_time = datetime.datetime.now(pytz.timezone('Europe/Berlin'))
utc_time = datetime.datetime.now(datetime.timezone.utc)
print(local_time - utc_time)
I thought a timezone is simply an offset (depending on factors such as the date and the location with DST and changing definitions over time... so not that simple, but still an offset). So a timezone-aware datetime I thought would simply be:
utc_time == '12:34'
+ timezone is Europe/Berlin in UTC 2018-01-01 at 12:34
=> local time = (utc + local timezone) = 2018-01-01 at 13:34
Then I thought, the difference between two datetime objects should be equal to the difference to the UTC at the same point in time (not considering the thought-construct of timezones).
Hence, if I execute "datetime.now" at (about) the same point in time and "assign" it to different time zones, the difference should be on the order of milliseconds that passed between the two commands.
But it actually is -1 day, 23:59:59.999982.
Found it; it's just a representation issue:
>>> print(local_time)
2018-03-13 14:01:14.973876+01:00
>>> print(utc_time)
2018-03-13 13:01:14.973899+00:00
>>> print(utc_time - local_time)
0:00:00.000023
>>> print(local_time - utc_time)
-1 day, 23:59:59.999977
>>> print((local_time - utc_time).total_seconds())
-2.3e-05
so it is -1 day + 23:59:59.999977

Python convert military time user input and calculate time worked (datetime.timedelta)

Noob here,
I'm stuck at trying to present user input in military time into standard time. The code works so far, but I need to subtract 12 hours from the end time to display in standard time. How do I do this using datetime.time? Also, do I need to convert the original user input to an integer to perform datetime.timedelta calculations? Previous questions don't seem to answer my coding questions.
My code is:
def timeconvert():
print "Hello and welcome to Python Payroll 1.0."
print ""
# User input for start time. Variable stored.
start = raw_input("Enter your check-in time in military format (0900): ")
# User input for end time. Variable stored.
end = raw_input("Enter your check-out time in military format (1700): ")
print ""
# ---------------------------------------------------------------------------
# Present user input in standard time format hhmm = hh:mm
# ---------------------------------------------------------------------------
import datetime, time
convert_start = datetime.time(hour=int(start[0:2]), minute=int(start[2:4]))
# need to find a way to subtract 12 from the hour to present end time in standard time
convert_end = datetime.time(hour=int(end[0:2]), minute=int(end[2:4]))
print 'You started at', convert_start.strftime("%H:%M"),'am', 'and ended at', convert_end.strftime("%H:%M"), 'pm'
# ---------------------------------------------------------------------------
# Use timedelta to caculate time worked.
# ---------------------------------------------------------------------------
# print datetime.timedelta
timeconvert()
raw_input("Press ENTER to exit program") # Closes program.
Thanks.
You can use strftime("%I:%M %p") to get standard 12 hour formatting with "AM" or "PM" at the end. See the Python documentation for more details on datetime string formatting.
Also, while it is not natively supported, you can simply use the two datetime.time instances to do your calculation as part of the timedelata constructor.
The below code should suffice, though proper error checking should definitely be used. ;)
--ap
start = raw_input("Enter your check-in time in military format (0900): ")
end = raw_input("Enter your check-out time in military format (1700): ")
# convert user input to datetime instances
start_t = datetime.time(hour=int(start[0:2]), minute=int(start[2:4]))
end_t = datetime.time(hour=int(end[0:2]), minute=int(end[2:4]))
delta_t = datetime.timedelta(
hours = (end_t.hour - start_t.hour),
minutes = (end_t.minute - start_t.minute)
)
# datetime format
fmt = "%I:%M %p"
print 'You started at %s and ended at %s' % (start_t.strftime(fmt), end_t.strftime(fmt))
print 'You worked for %s' % (delta_t)
def time12hr(string):
hours = string[:2]
minutes = string[2:]
x = " "
if int(hours) == 12:
x = "p.m."
hours = "12"
elif int(hours) == 00:
x = "a.m."
hours = "12"
elif int(hours) > 12:
x = "p.m."
hours = str(int(hours) - 12)
else:
x = "a.m."
return "%s:%s %s"%(hours ,minutes,x)
print time12hr('1202')
print time12hr('1200')
print time12hr('0059')
print time12hr('1301')
print time12hr('0000')

Groovy: How do you initialise and compare date/time values from different timezones?

I need to standardise and compare date/time fields that are in differnt timezones. eg How do you find the time difference between the following two times?...
"18-05-2012 09:29:41 +0800"
"18-05-2012 09:29:21 +0900"
What's the best way to initialise standard varaibles with the date/time?
The output needs to display the difference and normalised data in a timezone (eg +0100) that is different to the incoming values and different to the local environment.
Expected Output:
18-05-2012 02:29:41 +0100
18-05-2012 01:29:21 +0100
Difference: 01:00:20
import java.text.SimpleDateFormat
def dates = ["18-05-2012 09:29:41 +0800",
"18-05-2012 09:29:21 +0900"].collect{
new SimpleDateFormat("dd-MM-yyyy HH:mm:ss Z").parse(it)
}
def dayDiffFormatter = new SimpleDateFormat("HH:mm:ss")
dayDiffFormatter.setTimeZone(TimeZone.getTimeZone("UTC"))
println dates[0]
println dates[1]
println "Difference "+dayDiffFormatter.format(new Date(dates[0].time-dates[1].time))
wow. doesn't look readable, does it?
Or, use the JodaTime package
#Grab( 'joda-time:joda-time:2.1' )
import org.joda.time.*
import org.joda.time.format.*
String a = "18-05-2012 09:29:41 +0800"
String b = "18-05-2012 09:29:21 +0900"
DateTimeFormatter dtf = DateTimeFormat.forPattern( "dd-MM-yyyy HH:mm:ss Z" );
def start = dtf.parseDateTime( a )
def end = dtf.parseDateTime( b )
assert 1 == Hours.hoursBetween( end, start ).hours
Solution:
Groovy/Java Date objects are stored as the number of milliseconds after
1970 and so do not contain any timezone information directly
Use Date.parse method to initialise the new date to the specified format
Use SimpleDateFormat class to specify the required output format
Use SimpleDateFormat.setTimeZone to specifiy the timezone of the output
data
By using European/London timezone rather than GMT it will
automatically adjusts for day light savings time
See here for a full list of the options for date time patterns
-
import java.text.SimpleDateFormat
import java.text.DateFormat
//Initialise the dates by parsing to the specified format
Date timeDate1 = new Date().parse("dd-MM-yyyy HH:mm:ss Z","18-05-2012 09:29:41 +0800")
Date timeDate2 = new Date().parse("dd-MM-yyyy HH:mm:ss Z","18-05-2012 09:29:21 +0900")
DateFormat yearTimeformatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss Z")
DateFormat dayDifferenceFormatter= new SimpleDateFormat("HH:mm:ss") //All times differences will be less than a day
// The output should contain the format in UK time (including day light savings if necessary)
yearTimeformatter.setTimeZone(TimeZone.getTimeZone("Europe/London"))
// Set to UTC. This is to store only the difference so we don't want the formatter making further adjustments
dayDifferenceFormatter.setTimeZone(TimeZone.getTimeZone("UTC"))
// Calculate difference by first converting to the number of milliseconds
msDiff = timeDate1.getTime() - timeDate2.getTime()
Date differenceDate = new Date(msDiff)
println yearTimeformatter.format(timeDate1)
println yearTimeformatter.format(timeDate2)
println "Difference " + dayDifferenceFormatter.format(differenceDate)

Erlang: timestamp with time zone arithmetics

What is the best way to add/subtract units to/from specific timestamp with respect to time zone in Erlang?
From what I've found, calendar of stdlib can work with either local or UTC time zone, no more. Moreover, arithmetics is recommended to do in UTC time zone only (the reason is obvious).
What should I do if, for instance, I need to add 1 month to {{2011,3,24},{11,13,15}} in, let's say, CET (Central European Time) and local (system) time zone is not CET? That is not even the same as converting this timestamp to UTC, adding 31 * 24 * 60 * 60 seconds and converting back to CET (that will give {{2011,4,24},{12,13,15}} instead of {{2011,4,24},{11,13,15}}). By the way we can't do even such a thing if CET is not local time zone with stdlib.
The answers I found googling are:
setenv to make local time zone = needed time zone (that is very ugly first of all; then it will only allow to convert needed time zone to utc and do arithmetics respective to utc, not the needed time zone)
open_port to linux date util and do arithmetics there (not that ugly; rather slow; needs some parsing, because the protocol between erlang and date will be textual)
port driver or erl_interface to C using its standard library (not ugly at all; but I didn't find ready to use solution and I'm not that good at C to write one)
The ideal solution would be something written in Erlang using OS timezone info, but I didn't find any.
Now I'm stuck to solution 2 (open_port to date util). Is there a better way?
Thanks in advance.
P. S. There was a similar issue, but no good answer there Time zone list issue
port_helper.erl
-module(port_helper).
-export([get_stdout/1]).
get_stdout(Port) ->
loop(Port, []).
loop(Port, DataAcc) ->
receive
{Port, {data, Data}} ->
loop(Port, DataAcc ++ Data);
{Port, eof} ->
DataAcc
end.
timestamp_with_time_zone.erl
-module(timestamp_with_time_zone).
-export([to_time_zone/2, to_universal_time/1, modify/2]).
to_time_zone({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}, OutputTimeZone) ->
InputPattern = "~4.10.0B-~2.10.0B-~2.10.0B ~2.10.0B:~2.10.0B:~2.10.0B",
InputDeep = io_lib:format(InputPattern, [Year, Month, Day, Hour, Minute, Second]),
Input = lists:flatten(InputDeep),
{external_date(Input, TimeZone, OutputTimeZone), OutputTimeZone}.
to_universal_time({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}) ->
{Timestamp, "UTC"} = to_time_zone({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}, "UTC"),
Timestamp.
modify({{{Year, Month, Day}, {Hour, Minute, Second}}, TimeZone}, {Times, Unit}) ->
if
Times > 0 ->
TimesModifier = "";
Times < 0 ->
TimesModifier = " ago"
end,
InputPattern = "~4.10.0B-~2.10.0B-~2.10.0B ~2.10.0B:~2.10.0B:~2.10.0B ~.10B ~s~s",
InputDeep = io_lib:format(InputPattern, [Year, Month, Day, Hour, Minute, Second, abs(Times), Unit, TimesModifier]),
Input = lists:flatten(InputDeep),
external_date(Input, TimeZone, TimeZone).
external_date(Input, InputTimeZone, OutputTimeZone) ->
CmdPattern = "date --date 'TZ=\"~s\" ~s' +%Y%m%d%H%M%S",
CmdDeep = io_lib:format(CmdPattern, [InputTimeZone, Input]),
Cmd = lists:flatten(CmdDeep),
Port = open_port({spawn, Cmd}, [{env, [{"TZ", OutputTimeZone}]}, eof, stderr_to_stdout]),
ResultString = port_helper:get_stdout(Port),
case io_lib:fread("~4d~2d~2d~2d~2d~2d", ResultString) of
{ok, [YearNew, MonthNew, DayNew, HourNew, MinuteNew, SecondNew], _LeftOverChars} ->
{{YearNew, MonthNew, DayNew}, {HourNew, MinuteNew, SecondNew}}
end.

Resources