in Power Automate, how can I convert long-format datetime strings? - power-automate

In a Power Automate / MSFlow flow, I receive a string like this:
Saturday, July 31, 2021 1:35 AM  |  (UTC+01:00) Dublin, Edinburgh, Lisbon, London
I need to convert it to the format Sharepoint expects, i.e. a ISO 8601 for UTC:
YYYY-MM-DDTHH:MM:SS
I painfully built a flow that does most of the work; however, at the thought of having to manually manage the timezone offset my heart finally gave out. It's shocking that in 2021 a product like this cannot parse a datetime like we could do in any language in 1995.
So my question is: what's the easiest way to parse this datetime correctly in PA/Flow...?

I followed the MS reference:
Workflow definition language functions reference: formatDateTime
And the way to go was with "formatDateTime" function:
formatDateTime('<timestamp>', '<format>'?)
But, before that, the timestamp should be reformated in your case.
My approach will be the following:
Let's assume that the input string will be stored in a variable named timestamp_original.
Take the part before "|" character from the timestamp_original. and remove the Day (at the beginning) from the result.
pass the result to the formatDateTime function.
Use the convertTimeZone function to achieve the TimeZone conversion. (but this part is not working as I expected).
So the final result should be obtained by using the next expressions:
convertTimeZone(formatDateTime(first( split( substring(variables('timestamp_original'), add(2, indexOf(variables('timestamp_original'),','))) , '|' ) )), 'Central Europe Standard Time', 'Greenwich Standard Time')
The solution to the point 3, should be extracting the TimeZone from the timestamp_original string:
trim(first(split(last( split(variables('timestamp_original'), '(' ) ), ')')))
And add some logic to test if this TimeZone contains "UTC+" or "UTC-" and add or extract hours from the obtained timestamp.
I think you can do this.
It should be noted that the variable 'timestamp_original' should be initially in the next format (as the OP mentionned):
Saturday, July 31, 2021 1:35 AM | (UTC+01:00) Dublin, Edinburgh, Lisbon, London
So the result will be: (using the convertTimeZone function)
2021-07-30T23:35:00.0000000
And without using the convertTimeZone function:
2021-07-31T01:35:00.0000000
I hope this has helped. Good luck.

Related

Parsing a string into a ZonedDateTime with a DateTimeFormatter

I'm trying to parse this String into a ZonedDateTime:
"Mon 14 Aug 2017 02:00 AM CEST"
Here my last try:
System.out.println("Test ZonedDateTime: " + ZonedDateTime.parse(
"Mon 14 Aug 2017 02:00 AM CEST",
DateTimeFormatter.ofPattern("EEEE dd M yyyy KK:mm a z")));
And the response:
Exception in thread "main" java.time.format.DateTimeParseException: Text 'Mon 14 Aug 2017 02:00 AM CEST' could not be parsed at index 0
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.ZonedDateTime.parse(ZonedDateTime.java:597)
at be.hypertux.test.localtime.Main.main(Main.java:17)
Any ideas?
One problem is that short timezone names like CEST and CET are ambiguous and not standard. The ideal is to use IANA timezones names (always in the format Continent/City, like America/Sao_Paulo or Europe/Berlin).
I'm assuming that CEST is the Central Europe Summer Time, which is used by lots of different countries (that's why it's ambiguous: you can't know which country or region it is, because it's a too broad range).
Although most abbreviations are not recognized (due to its ambiguity), some "defaults" are assumed for retro-compatibility reasons. In the version I'm using (JDK 1.8.0_131), it defaults to Europe/Paris, but not sure if that's what you need. And it's not guaranteed to work for all abbreviations. In this case, you can define a preferred timezone to be used (and that will an arbitrary choice, but there's no other way since CEST is ambiguous).
Another problem is that the month and day of week are in English (Aug and Mon), and you didn't specify a java.util.Locale. In this case, the DateTimeFormatter takes the system's default locale (and it's probably not English - check the value of Locale.getDefault()). Anyway, the default locale can be changed without notice, even at runtime, so it's better to specify one when you're dealing with localized data (like month and day of week names).
So, you must specify a locale and define an arbitrary timezone as the preferred one to be used when an ambiguous name like CEST is found. For that, you can use a java.time.format.DateTimeFormatterBuilder, a set of preferred timezones and a java.time.format.TextStyle:
// create set of preferred timezones
Set<ZoneId> zones = new HashSet<>();
// my arbitrary choice for CEST
zones.add(ZoneId.of("Europe/Brussels"));
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
// date and time
.appendPattern("EEE dd MMM yyyy hh:mm a ")
// timezone short name with custom set of preferred zones
.appendZoneText(TextStyle.SHORT, zones)
// create formatter (use English locale for month and day of week)
.toFormatter(Locale.ENGLISH);
String input = "Mon 14 Aug 2017 02:00 AM CEST";
System.out.println(ZonedDateTime.parse(input, formatter));
The output will be:
2017-08-14T02:00+02:00[Europe/Brussels]
Note that I used Europe/Brussels as the preferred timezone. You can check all the available zone names (and choose accordingly) with ZoneId.getAvailableZoneIds().
I'm using hh for the hours, which is the hour-clock-of-am-pm field (values from 1 to 12). But in your code you used KK, which is the hour-of-am-pm field (values from 0 to 11). Check which one is best for your case.
A timezone is the set of all different offsets that a region had, has and will have during its history, and the dates when Daylight Saving Time starts and ends, etc. If 2 regions had some difference in this history, they'll have different timezones (even though they use the same rules today).
Just because Paris and Brussels use the same rules today (CET and CEST), it doesn't mean it'll be like this forever (because timezones rules are defined by governments and laws and there's no guarantee that they won't be changed at any time in the future).
That's why you must define some specific timezone instead of relying on ambiguous short names (even though their use is common and widespread).
In order for your format string to work, your date would need to be formatted like so: Monday 14 8 2017 02:00 AM CEST
Take out an E and add a couple of Ms and that should do it.

Parse hours from string with space delimiter

I have file strings that contain dates in their heading, stuff such as 2017-03-06 092328 - iPhone - Music Show - street performance, while walking the dog.m4a
I would like to parse the date our of this string, because I need to print it in a podcast friendly format.
I'm able to parse out the date, but for some reason the time component refuses to be parsed out :)
Date.strptime("2017-03-06 092328", "%Y-%m-%d %H%M%S").strftime(%Y-%m-%d %H%M%S)
Expected output:
"2017-03-06 092328"
Actual output
"2017-03-06 000000"
Your problem is that Date is (what a surprise!) a date, as in, "Not a time, just a date".
require 'time'
Time.strptime("2017-03-06 092328", "%Y-%m-%d %H%M%S").strftime("%Y-%m-%d %H:%M:%S")
#=> "2017-03-06 09:23:28"
To be fair :
the documentation of Time#strptime mentions that it's based on Date#strptime
Date._parse("2017-03-06 09:23:28") will happily return {:hour=>9, :min=>23, :sec=>28, :year=>2017, :mon=>3, :mday=>6}
If you find it confusing that a Time object has a date and a time but that Date just has a date, you could use DateTime.

How to validate a date in Xquery

If I have a date in YYYYMMDD format how to validate in Xquery version "1.0", so that it checks for month and year are valid and if say they are valid then a leap year with month as 02 can have a date 29 else a max 28.
Several integration tools such as Oracle Fusion Middleware implement Xquery version "1.0" not "3.0"
First of all, although your use case is rather simple: generally avoid tampering with dates (and especially times) on your own, and always rely on already implemented functionality, handling date and time is horribly complicated if you want to do it right.
Convert the string to a representation that XQuery's date functions are able to parse. If you can construct a date from the string, it is valid; if an error occurs, it is invalid. Dates can be constructed using xs:date($string). One way to convert the string would be using using substring(...) and string-join(...):
xs:date(string-join((substring($date, 1, 4), substring($date, 5, 2), substring($date, 7, 2)), '-'))
To catch an error, use a try/catch block.

Jmeter - get current date and time

I want to get the current date and time as example date: 11/10/2014 and time 8:30 am or 6:00 pm and pass it as parameters to my Jmeter test. Can some help me do this.
Use __time function:
${__time(dd/MM/yyyy,)}
${__time(hh:mm a,)}
Since JMeter 3.3, there are two new functions that let you compute a time:
__timeShift
"The timeShift function returns a date in the given format with the specified amount of seconds, minutes, hours, days or months added" and
__RandomDate
"The RandomDate function returns a random date that lies between the given start date and end date values."
Since JMeter 4.0:
dateTimeConvert
Convert a date or time from source to target format
If you're looking to learn jmeter correctly, this book will help you.
it seems to be the java SimpleDateFormat : http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
here are some tests i did around 11:30pm on the 20th of May 2015
${__time(dd-mmm-yyyy HHmmss)} 20-032-2015 233224
${__time(d-MMM-yyyy hhmmss)} 20-May-2015 113224
${__time(dd-m-yyyy hhmmss)} 20-32-2015 113224
${__time(D-M-yyyy hhmmss)} 140-5-2015 113224
${__time(DD-MM-yyyy)} 140-05-2015
JMeter is using java SimpleDateFormat
For UTC with timezone use this
${__time(yyyy-MM-dd'T'hh:mm:ssX)}
Use ${__time(yyyy-MM-dd'T'hh:mm:ss)} to convert time into a particular timeformat.
Here are other formats that you can use:
yyyy/MM/dd HH:mm:ss.SSS
yyyy/MM/dd HH:mm:ss
yyyy-MM-dd HH:mm:ss.SSS
yyyy-MM-dd HH:mm:ss
MM/dd/yy HH:mm:ss
You can use Z character to get milliseconds too.
For example:
yyyy/MM/dd HH:mm:ssZ => 2017-01-25T10:29:00-0700
yyyy/MM/dd HH:mm:ss.SSS'Z' => 2017-01-25T10:28:49.549Z
Most of the time yyyy/MM/dd HH:mm:ss.SSS'Z' is required in some APIs. It is better to know how to convert time into this format.
Actually, for UTC I used Z instead of X, e.g.
${__time(yyyy-MM-dd'T'hh:mm:ssZ)}
which gave me:
2017-09-14T09:24:54-0400
Use this format:
${__time(yyyy-MM-dd'T'hh:mm:ss.SS'Z')}
Which will give you:
2018-01-16T08:32:28.75Z
Should have double quotes surrounding the ${}
String todaysDate = "${__time(yyyy-MM-dd'T'HH:mm:ss.SSS'Z')}";

Paypal date formatting: what is "HH:MM:SS DD Mmm YY, YYYY PST"?

I'm looking at the PayPal IPN docs, and it says the datetime stamps of their strings are formatted as:
HH:MM:SS DD Mmm YY, YYYY PST
So year is specified twice?
Once in double digits, and another with 4 digits?
This looks bizarre.
This seems to be a bug in the documentation. The actual format should be "HH:MM:SS Mmm DD, YYYY PST" (e.g. "08:30:06 Apr 19, 2017 PDT")
Actually in PHP you need to use date("Y-m-d\TH:i:s\Z") . That will result in something that looks like 2012-04-30T00:05:47Z -- I didn't notice a difference between urlencoded and non.
Where are you guys finding this info? This information is elusive in their documentation and cost me an hour or two of hunting and trying stuff. The only place I see this format is in the TIMESTAMP field. Having a hard time with the PayPal NVP API's PROFILESTARTDATE for CreateRecurringPaymentsProfile and a "Subscription start date should be valid" error.
For php, the syntax is date("G:i:s M m, Y T");
this is the correct format according to their documentation - 2010-03-27T12:34:49Z
so it is - YYYY-MM-DDTHH:MM:SSZ (I don't know what the T in the middle and Z is but it's constant for all the dates)
I've created PayPal NVP library in Java, so if you want to check how it works, or use it,
you are more than welcome. it's on sourceforge - payapal-nvp.sourceforge.net
Complete date plus hours, minutes, seconds and a decimal fraction of a
second
YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
Where TZD = time zone designator (Z or +hh:mm or -hh:mm)
Example
1994-11-05T08:15:30-05:00 corresponds to November 5, 1994, 8:15:30 am, US Eastern Standard Time.
1994-11-05T13:15:30Z corresponds to the same instant.
https://www.w3.org/TR/NOTE-datetime
PayPal Format to Any format 100% working and easy copy Paste
$payPalFormat = "18:30:30 Feb 28, 2008 PST";
$subrotoFormat = date('Y-m-d', strtotime($payPalFormat));
Result: 2008-02-29
All Format: https://www.w3schools.com/php/func_date_date.asp
https://gist.github.com/subrotoice/d820863ce65eb0d8434a47a76d005df4 (Subroto Biswas Gist)
Actually, I think the right format is: yyyy-MM-ddTHH:MM:ssZ
The case is important.

Resources