PowerShell time conversion to UTC from a GMT+1 string - powershell

i use PowerShell for scripting some stuff.
Actual i got a string from a logfile - this one i prepared a timestamp like this example:
$timestamp = $timestampDate + " " + $timestampTime
#timestamp: 2020.11.16 06:03:27
This timestamp is a GMT+1 timestamp from my timezone but i need it in UTC (wintertime).
So i try:
get-date('2020.11.16 06:03:27') -f "yyyy.MM.dd hh:mm:ss z"
2020.11.16 06:03:27 +1
Get-Date('2020.11.16 06:03:27') -Format FileDateTimeUniversal
20201116T0503270000Z
Now i try how i could format the result to 2020.11.16 05:03:27 in a easy way without string manipulation (my DB field is without timezone)
Thanks a lot.

Related

talend format yyyy-MM-dd'T'HH:mm:ss.SSSz to yyyy-mm-dd HH:mm:ss

I am trying to change the date format in txmlmap component but its not working
i want change date format
from yyyy-MM-dd'T'HH:mm:ss.SSSz to yyyy-mm-dd HH:mm:ss
expected output:- yyyy-mm-dd HH:mm:ss
You can parse your string to a date using your source pattern and then format that date to a string using your target pattern:
TalendDate.formatDate("yyyy-mm-dd HH:mm:ss", TalendDate.parseDate("yyyy-MM-dd'T'HH:mm:ss.SSSz", myDateString))
In almost all coding languages format is text, while date is a double. That means you must first make a date of the first expression, before setting the new format of that date. But in Your case the 'T' is some kind of special format that need to be replaced with a blanck space. I have no idea about what it would look like in talend but in VB it would look like this:
' from yyyy-MM-dd'T'HH:mm:ss.SSSz to yyyy-mm-dd HH:mm:ss
DateTxt = "2022-12-01'T'22:45:10"
DateTxt = Replace(DateTxt, "'T'", " ")
MyDate = CDate(DateTxt)
MsgBox Format(MyDate, "yyyy-mm-dd HH:mm:ss")

Powershell string to unix time with correct timezone

I'm collecting a timestamp value and trying to transform it to a Unix format.
To do that, I'm using ParseExact method, like so:
$FILETIME = "20220709101112"
$EPOCHTIME = [datetime]::ParseExact($FILETIME,"yyyyMMddHHmmss",$null) | Get-Date -UFormat "%s"
echo $EPOCHTIME
1657361472
Get-Date transforms the timestamp to Unix format correctly, but there's an issue.
The returned value uses the local timezone (UTC-3), not UTC-0.
Therefore, in another system that value might be displayed with the wrong timezone.
I've tried to add 3 hours, but it appended the number instead.
$EPOCHTIME = $EPOCHTIME + 10800
echo $EPOCHTIME
165736147210800
How can I convert that timestamp correctly?
Ok, so here's one way to do it (borrowing from https://stackoverflow.com/a/246529/3156906).
The key is to find the TimeZoneInfo for the timezone the $FILETIME string is local to, and use that to convert the local time to UTC before converting to a Unix epoch timestamp.
# datetime string that is local to UTC-3,
# (equivalent to "2022-07-09 13:11:12 UTC")
$FILETIME = "20220709101112";
# because there's no timezone component in the custom
# format string (e.g. "z" or "zz") this gets converted
# to a datetime with "Kind = DateTimeKind.Unspecified"
# (see https://learn.microsoft.com/en-us/dotnet/api/system.datetime.parseexact?view=net-6.0#system-datetime-parseexact(system-string-system-string-system-iformatprovider))
$TIMESTAMP = [datetime]::ParseExact($FILETIME, "yyyyMMddHHmmss", $null);
# DateTime : 09 July 2022 10:11:12
# Kind : Unspecified
# get a reference to the timezone the original date
# string is stored local to. I guessed this by looking
# at the results of "[TimeZoneInfo]::GetSystemTimeZones()"
# and taking a timezone with -3:00 from UTC and no daylight savings
# but maybe there's a better match for your source data
$tz = [TimeZoneInfo]::FindSystemTimeZoneById("SA Eastern Standard Time");
# Id : SA Eastern Standard Time
# DisplayName : (UTC-03:00) Cayenne, Fortaleza
# StandardName : SA Eastern Standard Time
# DaylightName : SA Eastern Summer Time
# BaseUtcOffset : -03:00:00
# SupportsDaylightSavingTime : False
# this is the magic bit - treat $TIMESTAMP as a local time in
# timezone $tz, and convert it to UTC using the BaseUtcOffset
# and daylight saving rules for $tz
$UTCTIME = [TimeZoneInfo]::ConvertTimeToUtc($TIMESTAMP, $tz);
# DateTime : 09 July 2022 13:11:12
# Kind : Utc
# now convert it to a unix epoch timestamp
$EPOCHTIME = $UTCTIME | Get-Date -UFormat "%s";
# 1657372272
Bonus Round
You get the Unix epoch timestamp 1657361472 because the current timezone on the computer where you're running your script is UTC, which is 3 hours offset from the timezone the string is local to.
Notes on DateTime.ParseExact Method
If s does not represent a time in a particular time zone and the parse
operation succeeds, the Kind property of the returned DateTime value is
DateTimeKind.Unspecified. If s does represent the time in a particular time
zone and format allows time zone information to be present (for example, if
format is equal to the "o", "r", or "u" standard format specifiers, or if it
contains the "z", "zz", or "zzz" custom format specifiers), the Kind
property of the returned DateTime value is DateTimeKind.Local.
This question has been answered in this post:
Get formatted universal date / time
Essentially, it depends on the version of PowerShell that you're using. If it's Powershell 7.1+, then you can do:
Get-Date -AsUTC -UFormat "%s"
Otherwise, if it's a lower version, you need to use
Get-Date ([datetime]::UtcNow) -UFormat "%s"

Current timestamp in ISO 8601 UTC time (ie: 2013-11-03T00:45:54+02:00)

Can someone please help me how to format timestamp in ISO 8601 UTC time?
I want the date to be formatted like this 2020-10-03T00:45:54+02:00
I have tried this in App Script.
Utilities.formatDate(new Date(), "UTC", "yyyy-MM-dd'T'HH:mm:ssZZZ");
It is getting this output 2020-10-03T08:50:18+0000
I want the timezone to be formatted like this TwoDigitHours : Minutes
Use Date.toISOString() for UTC ISO8601 string:
/*<ignore>*/console.config({maximize:true,timeStamps:false,autoScroll:false});/*</ignore>*/
console.log(new Date().toISOString())
<!-- https://meta.stackoverflow.com/a/375985/ --> <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
Utilities.formatDate accepts 3 arguments:
Date object
Timezone
SimpleDateFormat string
For, ISO8601 timestring use X instead of Z
For a specific timezone, use that timezone(GMT+2) as second argument instead of UTC
Utilities.formatDate(new Date(),"GMT+2" , "yyyy-MM-dd'T'HH:mm:ssXXX");
Alternatively, Use Session.getScriptTimeZone() or Spreadsheet.getSpreadsheetTimeZone() instead for the second argument:
Utilities.formatDate(new Date(),Session.getScriptTimeZone(), "yyyy-MM-dd'T'HH:mm:ssXXX");
//Or
Utilities.formatDate(new Date(),Spreadsheet.getSpreadsheetTimeZone(), "yyyy-MM-dd'T'HH:mm:ssXXX");

How to convert powershell UTC datetime object to EST

I have date time strings coming in, formatted like the following:
2017-08-03T12:30:00.000Z
I need to be able to convert these to EST. Every function I have tried throws one error or another, typically being:
"String was not recognized as a valid DateTime."
I have tried variations of the below:
$time = '2017-08-03T12:30:00.000Z'
[datetime]$datetime = $time
$culture = [Globalization.CultureInfo]::InvariantCulture
[DateTime]::ParseExact($datetime, 'MM-dd-yyyy HH:mm:ss', $culture)
I think it has something to do with how the Date Time string I am referencing has the **T** and then the UTC time, but can't figure out what to do about it. Maybe I should parse out the time, convert it and then reattach to the first part of the string, the date, and combine them together for the final output? Seems like way too much work and a solution which would cause potential errors in the future.
You should be able to convert a Zulu time string to a DateTime value simply by casting it. However, the resulting value will be in local time, so you should convert it back to UTC for further calculations:
$timestamp = '2017-08-03T12:30:00.000Z'
$datetime = ([DateTime]$timestamp).ToUniversalTime()
Then you can use the TimeZoneInfo class to convert the UTC timestamp to the desired timezone:
[TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($datetime, 'Eastern Standard Time')
Use [TimeZoneInfo]::GetSystemTimeZones() | Select-Object Id, DisplayName to get a list of the recognized timezones.
Try using the static ConvertTimeBySystemTimeZoneId() method of the [System.TimeZoneInfo] class:
$time = '2017-08-03T12:30:00.000Z'
$result = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId((Get-Date -Date $time), 'Eastern Standard Time')
The returned $result is a [DateTime].
BTW, if you ever need to convert it back, here's how:
Get-Date -Date $result -Format FileDateTimeUniversal
Hope this helps.

How to set client specific timezone and date

pardon me if it seems to be a duplicate question.
I have seen many posts already on this topic. However after trying many examples could not find the solution to my problem.
I tried this code
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd yyyy", Locale.ENGLISH )
Date newDate = sdf.parse(sdf.format( new Date( dateTimeString ) ) )
However the second line of code always converts the date to the server specific date and timezone which i don't want. I also tried the following
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss zzz", Locale.ENGLISH )
log.info "+++++++++++++++++hidden date ++++++++ " + params.hiddenGameDateTime.substring(35, 38)
log.info "x = " + sdf.format( new Date ( params.hiddenGameDateTime ))
String tzone = params.hiddenGameDateTime.substring(35, 38)
sdf.setTimeZone( TimeZone.getTimeZone( tzone ) )
log.info "Timezone = " + sdf.getTimeZone().getDisplayName()
Please note that
sdf.format( new Date( dateTimeString ) )
gives me the desired result, however it gives me the string value of the date and the actual value to be stored in database is of the Data type date which can't hold the string value.
the value for date and time in my case gets converted to PST date and time. how can i avoid this. The user input date with timezone should be stored in the database as it is with no change in date and timezone.
An observation: The constructor new Date( dateTimeString ) is deprecated. A better replacement would be something like that:
SimpleDateFormat sdfOriginal = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
Date d = sdfOriginal.parse(dateTimeString);
Furthermore: An expression like sdf.parse(sdf.format(...)) using the same format object does not make much sense.
But most important, your statement "the second line of code always converts the date to the server specific date and timezone" seems to be based on test output like:
System.out.println(newDate);
This implicitly uses toString() which is based on jvm default time zone, in your case the server time zone. But keep in mind, the internal state of j.u.Date does not reference any time zone. A Date is just a container for a long, namely the seconds since 1970-01-01T00:00:00Z in UTC time zone, that is a global time.
Additional remark:
If you need the client time zone (in a scenario with multiple users in different time zones) to create user-specific formatted date strings, then you indeed need to store the time zone preference of every user in the database, so you can use this information for output in an expression like:
SimpleDateFormat sdf = new SimpleDateFormat("{pattern}";
sdf.setTimeZone(TimeZone.getTimeZone("{user-preference-time-zone}");
String userOutput = sdf.format(date);
Date is always jvm timezone specific. You need to normalize it to standard time and store it in DB to cater with different timezone servers.