Round Off time to the upcoming nearest 15 minutes time using Groovy - datetime

I am trying to round off time to the upcoming 15 minutes time.
e.g :
2017-12-11T13:11:51.728Z to 2017-12-11T13:15:00.000Z
2017-12-11T13:21:51.728Z to 2017-12-11T13:30:00.000Z
Groovy code :
def currentTime = context.expand('${#Project#currentTime}')
log.info currentTime
date1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(currentTime)
//Round off the time nearest to the mod 15
Calendar calendar = Calendar.getInstance();
calendar.setTime(date1);
int unroundedMinutes = calendar.get(Calendar.MINUTE);
int mod = unroundedMinutes % 15;
log.info calendar.add(Calendar.MINUTE, mod < 8 ? -mod : (15-mod));
Output :
Mon Dec 11 14:32:32 IST 2017:INFO:2017-12-11T14:32:32.690Z
Mon Dec 11 14:32:32 IST 2017:INFO:null

Here you go:
In order to get the difference minutes, created a closure.
The closure gets called recursively if needed.
If the current minutes is divisible by 15, it won't adjust the time; that is the reason for adding third value in the list.
To be able to test with multiple values, used list of dates. You may use it for single value as well.
def timez = ['2017-12-11T13:11:51.728Z', '2017-12-11T13:21:51.728Z', '2017-12-11T13:30:00.000Z']
def dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
def roundValue = 15
//Change timezone if needed
def tz = 'IST'
TimeZone.setDefault(TimeZone.getTimeZone(tz))
Calendar calendar = Calendar.getInstance()
def getNearestMinutes
//Closure which gets called recursive
getNearestMinutes = { cmin, nearMin = roundValue ->
def tempResult = cmin % nearMin
if ( tempResult < nearMin && (0 < (nearMin - cmin)) ) {
return (nearMin - cmin)
} else {
return getNearestMinutes(cmin, nearMin+roundValue)
}
}
//Loop thru times and round the time
timez.each {
calendar.time = Date.parse(dateFormat,it)
def currentMinute = calendar.get(Calendar.MINUTE)
def cof = currentMinute % roundValue
if (cof) {
currentMinute += getNearestMinutes(currentMinute)
calendar.set(Calendar.MINUTE, currentMinute )
}
calendar.set(Calendar.SECOND, 0)
calendar.set(Calendar.MILLISECOND, 0)
log.info calendar.time.format(dateFormat)
}
You can quickly try it online demo
EDIT: Felt that the solution could be made something more simple than applying above difficult conditions.
Here is another solution to round time to near future 15 min.
Yet, easy to read code unlike multiple conditions in the first solution.
This is simple one using Switch statement
def timez = ['2017-12-11T13:11:51.728Z', '2017-12-11T13:21:51.728Z', '2017-12-11T13:30:00.000Z', '2017-12-11T13:46:00.000Z']
def dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
def roundValue = 15
//Change timezone if needed
def tz = 'IST'
TimeZone.setDefault(TimeZone.getTimeZone(tz))
Calendar calendar = Calendar.getInstance()
def getNexTime = { min ->
def result
switch(min) {
case 1..15:
result = 15
break
case 16..30:
result = 30
break
case 31..45:
result = 45
break
case 46..60:
result = 60
break
default:
result = 0
break
}
result
}
//Loop thru times and round the time
timez.each {
calendar.time = Date.parse(dateFormat,it)
def currentMinute = calendar.get(Calendar.MINUTE)
if (0 != getNexTime(currentMinute)) {
calendar.set(Calendar.MINUTE, getNexTime(currentMinute) )
}
calendar.set(Calendar.SECOND, 0)
calendar.set(Calendar.MILLISECOND, 0)
println calendar.time.format(dateFormat)
}

Related

How to use for loop to create multiple dates?

I have a function here that gets the date, and adds one week to it:
func thingy() {
let currentDate = Date()
var dateComponent = DateComponents()
dateComponent.day = 7
let futureDate = Calendar.current.date(byAdding: (dateComponent*i), to: currentDate)
print(futureDate!.formatted())
}
This gets the current date, adds one week to it, and prints out that date.
I want to get a for loop that will give the date, for example maybe 10 weeks in the future, maybe looking something like this:
for i in 1...num[ex: 11] {
let currentDate = Date()
var dateComponent = DateComponents()
dateComponent.day = 7
let futureDate = Calendar.current.date(byAdding: (dateComponent*i), to: currentDate)
let match = (title: "Test", date: futureDate)
}
I get this error:
Referencing operator function '*' on 'DurationProtocol' requires that 'DateComponents' conform to 'DurationProtocol'
How do I fix this?
I would advise adding .weekOfYear to the date. E.g., to get an array of Date representing the next ten weeks:
let calendar = Calendar.current
let today = calendar.startOfDay(for: Date())
let dates = (1 ... 10)
.compactMap { calendar.date(byAdding: .weekOfYear, value: $0, to: today) }

Working with Date, Time in Google Apps Script

I need help with some quick coding with google apps script, linking to my googlesheets spreadsheet.
In the googlespreadsheets, I have a cell with the value “26-Jun-2020”. It is a date.
I want to use google apps script to calculate the number of days difference between that date (“26-Jun-2020”) and today’s day, but it won’t do the calculation for me somehow.
If I print only “expiry_date[i]” using Logger.log(expiry_date[i]), it will provide the output “Fri Dec 17 2021 01:00:00 GMT-0500 (Eastern Standard Time) “
function Put_Options_Expiry_Alert() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Long equity (sell puts)");
//var timeZone = AdsApp.currentAccount().getTimeZone(); //Get timezone of current spreadsheet
var status = sheet.getRange("F:F").getValues();
var expiry_date = sheet.getRange("M:M").getValues();
var potential_capitaloutlay_USD = sheet.getRange("Z:Z").getValues();
Logger.log("Length of status = " + status.length);
Logger.log("Length of expiry_date = " + expiry_date.length);
Logger.log("Length of potential_capitaloutlay_USD = " + potential_capitaloutlay_USD.length);
for (var i = 0; i < status.length; i++) {
if (status[i] == "Entered") { //Evaluate if this is a live Put position
//Calculate the time difference of two dates using date2. getTime() – date1. getTime();
//Calculate the no. of days between two dates, divide the time difference of both the dates by no. of milliseconds in a day (1000*60*60*24)
Logger.log("expiry date is = "+expiry_date[i]);
Logger.log("today's date is = "+Date());
var days_to_expiry = dateDiffInDays(expiry_date[i],Date());
Logger.log(days_to_expiry);
}
}
}
// Function that returns the number of days difference between DateA and DateB
// DateA and DateB are javascript Date objects
function dateDiffInDays(DateA, DateB) {
var milliseconds_per_day = 1000 * 24 * 60; // number of milliseconds in a day
const utcA = Date.UTC(2021, DateA.getMonth(), DateA.getDate());
const utcB = Date.UTC(2020, DateB.getMonth(), DateB.getDate());
return Math.floor((utc2 - utc1) / milliseconds_per_day);
}
function timeDiffDays(Start, End) {
var day = 86400000;
var t1 = new Date(Start).valueOf();
var t2 = new Date(End).valueOf();
var d = t2 - t1;
return Math.floor(d / day);
}

Groovy: Export Data - How to set unix start time from now to a certain point in the past?

I am currently exporting data from Grafana. I do that using a script which looks like this one:
JsonSlurper slurper = new JsonSlurper()
println "Collect list of servers:"
def result = slurper.parse(new URL('http://xyz'))
def servers = [:].withDefault { [] }
result.data.each{ it ->
servers[it.server] = "${it.server};${it.app};${it.team}"
}
servers.sort().each { k, v -> println v}
println "Collect data for servers:"
Date currentDate = new Date();
Date fromDate = currentDate - 30
long unixTimeNow = currentDate.getTime() / 1000
long unixFromDate = fromDate.getTime() / 1000
long stepSec = 7200
boolean header = true
servers.sort().each{ server, label ->
File resultFile = new File("C:\\Users\\GrafanaExport${server}.csv")
if(resultFile.exists()) {
resultFile.delete()
}
def queries = [
['node_load1',"http://abc{server}.start${unixFromDate}&end=${unixTimeNow}&step=${stepSec}"],]
def resultTable = [:].withDefault { [";",";",";"] }
queries.eachWithIndex { q, i ->
println(q)
result = slurper.parse(new URL(q[1]))
result?.data?.result[0]?.values?.each{ it ->
resultTable[it[0]][i] = it[1] + ";"
}
}
if(header) {
resultFile << "timestamp;" + queries.collect{it[0]}.join(';') + '\n'
header = false
}
resultFile << label + '\n'
resultTable.sort().each { k, v ->
resultFile << "${k};${v.join('')}\n"
}
}
This works fine but what I want to get instead is not the data from now until some time ago but from a certain timestamp until some time ago. Because previously I already exported data and I would like to get the same dates/timestamps for the data. The previously exported data is stamped with this timestamps (snip of the example timestamps):
That means the data was exported every two hours (because of this a step of 7200 seconds) and at every full and in unix time every even hour. I now want to know how I need to amend my code in order to get the data for the same timestamps as before?
Thanks a lot!

How to find difference between two times in 24 hour format - Flutter?

I have to find the difference between two times in 24 hour format. I have the two time strings, Eg: 10:40 and 18:20. How can I find the difference between these two times in Flutter?
You can use intl package.
var format = DateFormat("HH:mm");
var one = format.parse("10:40");
var two = format.parse("18:20");
print("${two.difference(one)}"); // prints 7:40
A complete answer for perfect calculation is given bellow
String start_time = formateTime('12:00'); // or if '24:00'
String end_time = formateTime('24:00'); // or if '12:00
var format = DateFormat("HH:mm");
var start = format.parse(start_time);
var end = format.parse(end_time);
if (start.isAfter(end)) {
print('start is big');
print('difference = ${start.difference(end)}');
} else if(start.isBefore(end)){
print('end is big');
print('difference = ${end.difference(start)}');
}else{
print('difference = ${end.difference(start)}');
}

Difference Between Two localDate

I have a date returned by a json, it is in the following variable as string:
val dateEvent = "2019-12-28 21:00:00"
The calculation I need is to know how many days hours minutes are left with the current date.
I have found some solutions but these use as input "2019-12-28" and I have my format with the time included.
java.time
Since Java 9 you can do (sorry that I can write only Java code):
DateTimeFormatter jsonFormatter = DateTimeFormatter.ofPattern("u-M-d H:mm:ss");
String dateEvent = "2019-12-28 21:00:00";
Instant eventTime = LocalDateTime.parse(dateEvent, jsonFormatter)
.atOffset(ZoneOffset.UTC)
.toInstant();
Duration timeLeft = Duration.between(Instant.now(), eventTime);
System.out.format("%d days %d hours %d minutes%n",
timeLeft.toDays(), timeLeft.toHoursPart(), timeLeft.toMinutesPart());
When I ran the code just now, the output was:
145 days 4 hours 19 minutes
In Java 6, 7 and 8 the formatting of the duration is a bit more wordy, search for how.
Avoid SimpleDateFormat and friends
The SimpleDateFormat and Date classes used in the other answer are poorly designed and long outdated. In my most honest opinion no one should use them in 2019. java.time, the modern Java date and time API, is so much nicer to work with.
Use the following function:
fun counterTime(eventtime: String): String {
var day = 0
var hh = 0
var mm = 0
try {
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val eventDate = dateFormat.parse(eventtime)
val cDate = Date()
val timeDiff = eventDate.time - cDate.time
day = TimeUnit.MILLISECONDS.toDays(timeDiff).toInt()
hh = (TimeUnit.MILLISECONDS.toHours(timeDiff) - TimeUnit.DAYS.toHours(day.toLong())).toInt()
mm =
(TimeUnit.MILLISECONDS.toMinutes(timeDiff) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(timeDiff))).toInt()
} catch (e: ParseException) {
e.printStackTrace()
}
return if (day == 0) {
"$hh hour $mm min"
} else if (hh == 0) {
"$mm min"
} else {
"$day days $hh hour $mm min"
}
}
counterTime(2019-08-27 20:00:00)
This returns 24 days 6 hour 57 min
Note: The event date should always be a future date to the current date.

Resources