Subtract number of hours from current time in Java - datetime

I have a string that represents time duration of 54:34:41 i.e. 54 hours, 34 minutes, 41 seconds.
I would like to extract the 54 hours and subtract it from the current system time.
However when I run below I get java.time.format.DateTimeParseException: Text '54:34:41' could not be parsed: Invalid value for HourOfDay (valid values 0 - 23): 54
How can I extract 54 hours and subtract from current time?
private val formatterForTime: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss")
val timeDuration = formatterForTime.parse("54:34:41")
val currentTime = LocalDateTime.now()
val newTime = currentTime.minusHours(timeDuration.get(ChronoField.HOUR_OF_DAY).toLong())

tl;dr
ZonedDateTime
.now(
ZoneId.of( "Asia/Tokyo" )
)
.minusHours(
Integer.parseInt( "54:34:41".split( ":" )[0] )
)
Details
Parse hours
Get the number of hours.
int hours = Integer.parseInt( "54:34:41".split( ":" )[0] ) ;
ISO 8601
Your input text for a span-of-time does not comply with the ISO 8601 standard for date-time values. The java.time classes by default use the standard formats when parsing/generating text.
If instead of 54:34:41 you had PT54H34M41S, then we could use:
int hours = Duration.parse( "PT54H34M41S" ).toHours() ;
I recommend you stick with the standard format rather than the ambiguous clock-time format.
Capture current moment
Capture the current moment as seen in a particular time zone.
ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
Subtract hours
Subtract your hours.
ZonedDateTime earlier = zdt.minusHours( hours ) )

Related

NIFI Executescript UTC Error for unsupported operand type "+" in java.sql.Timestamp and timedelta

I am trying to split a flowfile into multiple flow files on the basis of adding a month to a date which i am getting in the coming flowfile.
eg.
{"to":"2019-12-31T00:00:00Z","from":"2019-03-19T15:36:48Z"}
be the dates i am getting in a flowfile . so i have to split this single flow file into 11 flowfiles with date ranges like
{"to":"2019-04-19","from":"2019-03-19"}
{"to":"2019-05-19","from":"2019-04-19"}
{"to":"2019-06-19","from":"2019-05-19"}
....... and so till
{"to":"2019-12-31","from":"2019-12-19"} .
i have been trying with example inputs to split files with this into day wise flowfiles:
`
begin = '2018-02-15'
end = '2018-04-23'
dt_start = datetime.strptime(begin, '%Y-%m-%d')
dt_end = datetime.strptime(end, '%Y-%m-%d')
one_day = timedelta(days = 1)
start_dates = [dt_start]
end_dates = []
today = dt_start
while today <= dt_end:
tomorrow = today + one_day
print(tomorrow)
`
but i get a error in my Execute script processor. nifi flow screenshot
Since you're using Jython, you may have to cast today to some Jython/Python time variable or call today.getTime() in order to do arithmetic operations on it.

Convert Unix Epoch Time to MSZ date and time

Does anyone of you have suggestions how to convert the Unix timestamp to ABAP MEZ/MESZ time and date?
The following code is from the ABAP-Reference, the code is for timestamps with lenght 15 or 21 but the Unix timestamp is currently 10 digits long.
DATA: time_stamp TYPE timestamp,
tz TYPE ttzz-tzone.
tz = 'MESZ'.
time_stamp = 15319830890000.
CONVERT TIME STAMP time_stamp TIME ZONE tz
INTO DATE DATA(dat) TIME DATA(tim)
DAYLIGHT SAVING TIME DATA(dst).
cl_demo_output=>write( |{ dat DATE = ISO } {
tim TIME = ISO } { dst }| ).
time_stamp = 15319830890000.
CONVERT TIME STAMP time_stamp TIME ZONE tz
INTO DATE dat TIME tim
DAYLIGHT SAVING TIME dst.
cl_demo_output=>write( |{ dat DATE = ISO } {
tim TIME = ISO } { dst }| ).
cl_demo_output=>display( ).
I solved the problem with this code. I am using now 13 digits epoche...
data: i(20) type n.
data: d type sy-datum."
data: t type sy-uzeit.
data: epoche type int8.
data: test type int8.
data: test2 type int8.
epoche = 1522836000000.
i = epoche / 1000.
d = '19700101'.
d = d + i div 86400.
t = i mod 86400.
write: d, t.
If you want to convert using a SAP time zone, this one can work too (no time to convert it to ABAP Objects):
FORM unixtime_2_date_time
USING
i_unixtime TYPE numeric
i_timezone TYPE timezone
CHANGING
e_date TYPE d
e_time TYPE t.
DATA l_tstmp_unix_era TYPE TZNTSTMPL.
DATA l_tstmp TYPE TZNTSTMPL.
CONSTANTS utc TYPE timezone value IS INITIAL.
CONVERT DATE '19700101' TIME '000000' INTO TIME STAMP l_tstmp_unix_era TIME ZONE utc.
l_tstmp = CL_ABAP_TSTMP=>add( tstmp = l_tstmp_unix_era secs = i_unixtime ).
CONVERT TIME STAMP l_tstmp TIME ZONE i_TIMEZONE INTO DATE e_date TIME e_time .
ENDFORM.
You can use cl_pco_utility Java utility class for that, particularly method convert_java_timestamp_to_abap. It perfectly accepts 10-character Unix time.
CLASS zcl_epoch DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
unix_time_to_timestamp
IMPORTING iv_timestamp TYPE timestamp.
ENDCLASS.
CLASS zcl_epoch IMPLEMENTATION.
METHOD unix_time_to_timestamp.
CONSTANTS: c_tzone TYPE ttzz-tzone VALUE 'CET'.
DATA: lv_timestamp_msec TYPE string,
lv_timestamp TYPE timestamp,
lv_date TYPE datum,
lv_time TYPE uzeit.
lv_timestamp_msec = iv_timestamp * 1000.
cl_pco_utility=>convert_java_timestamp_to_abap(
EXPORTING
iv_timestamp = lv_timestamp_msec
IMPORTING
ev_date = lv_date
ev_time = lv_time
).
lv_timestamp = lv_date && lv_time.
CONVERT TIME STAMP lv_timestamp TIME ZONE c_tzone INTO DATE lv_date TIME lv_time.
cl_demo_output=>display( |{ lv_date DATE = ISO } { lv_time TIME = ISO }| ).
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
zcl_epoch=>unix_time_to_timestamp( '1532196799' ).
It worth mentioning that MEZ/MSEZ are NOT standard abbreviations and should not be used. For example, MEZ is the same as CET. Look at list of common time zones here or here.
Also, it's better to stick to list of available time zones of your system, which is table TTZZ.
Just add the epoch time to '19700101' date with initial time.
DATA lv_initial_timestamp TYPE timestamp.
CONVERT DATE '19700101' TIME '000000' INTO TIME STAMP lv_initial_timestamp TIME ZONE sy-zonlo.
ev_timestamp = cl_abap_tstmp=>add( tstmp = lv_initial_timestamp secs = iv_epoch_timestamp ).
CONVERT TIME STAMP ev_timestamp TIME ZONE sy-zonlo INTO DATE ev_date TIME ev_time.
For MEZ/MESZ you can choose time zone accordingly.

SAS date formatting hours / minutes / seconds

Because my time data has some messy characters in it ( *, #, char, etc) I'm inputting the data in best.32 format and then using compress to remove the irrelevant char - time_1 = compress(Tim_original,'*#','l');
However, my data takes the form of mm:ss and hh:mm:ss and for some reason when I use time_1=input(time_1,time8.) to convert from the string to a num, it makes my mm into hours...! How do I covert my string to time/minutes and not have the minutes turned into hours with ":00" added at the end?
If your text only has one : then the informat TIME will take that to mean hh:mm and not mm:ss. You could just test your string and divide the result of the INPUT() function call by 60 to convert it.
data test;
input #1 timestr $8. ;
time1=input(timestr,time8.);
time2=input(timestr,time8.);
if countw(timestr,':') < 3 then time2=time2/60 ;
format time1 time2 time8.;
cards;
12:34
0:12:34
;

SAS (24 hour) time conversion to minutes

I am trying to convert 24 hour Time values to minutes
From:
(TIME)
17:00:00
16:55:00
17:30:00
To:
(NUM)
1060
993
1038
Currently I am multiplying the time values by 60 17*60, 16.55*60, 17.30*60
How would I accomplish this? am I doing it right? and what am I doing wrong?
SAS time values are stored as seconds. If it's truly a 'time' value, anyway, and not a character string. Thus, you can DIVIDE by 60, rather than multiplying.
data want;
input timeval TIME9.;
minutes=timeval/60;
format minutes BEST12.;
format timeval TIME9.;
put timeval= minutes=;
datalines;
17:00:00
16:55:00
17:30:00
;;;;
run;
If it's not stored as a time value (numeric) but as a string, you need to INPUT(timeval,TIME9.) in order to do that; so
minutes = input(timeval,TIME9.)/60;
would work.
No idea what this has to do with SQL, but in general, assuming that hours is 0-23 rather than 0-12 with an am/pm indicator, this pseudocode
( 60.0 * hours ) // convert 0-23 hours to minutes
+ minutes // minutes don't need conversion
+ ( seconds / 60.0 ) // convert 0-59 seconds to fractional minute
should give you the offset from start of day (midnight, 00:00:00) as a fractional number of minutes. If you've got an am/pm indicator, you need to factor that in, something like this:
( 60.0 * ( hours + ( isPM ? 12 : 0 ) ) ) // convert 0-23 hours to minutes
+ minutes // minutes don't need conversion
+ ( seconds / 60.0 ) // convert 0-59 seconds to fractional minutes

Math with MySQL timestamps in groovy

I need to subtract one timestamp from another in groovy and get the number of hours that has passed. The timestamps are coming from MySQL. When I do simple math I get numbers of days rounded off to zero integers.
endDate - startDate
gives rounded integer
I want a result of 2.35 hours, etc.
You can use groovy.time.TimeCategory like so:
// create two timestamps
import java.sql.Timestamp
def dates = ['2012/08/03 09:00', '2012/08/03 10:30']
def (Timestamp a, Timestamp b) = dates.collect {
new Timestamp( Date.parse( 'yyyy/MM/dd hh:mm', it ).time )
}
// Then compare them with TimeCategory
use(groovy.time.TimeCategory) {
def duration = b - a
println "${duration.days}d ${duration.hours}h ${duration.minutes}m"
}
Which will print:
0d 1h 30m

Resources