I am currently converting a date time value to unix time so that it can be inserted into a time series database (influxdb) using the following code:
(Get-Date -Date $_.timecreated -UFormat %s)
Unfortunately influx requires nano second resolution while the above gives me ms resolution. What is the best way to add nano second resolution that influx can accept as a valid unix timestamp? I have tries adding some 0000 characters at the end but that does not always work.
You will have to compute the unix timestamp yourself like this, by computing the offset from the unix epoch:
$utime = ((Get-Date -Date $_.timecreated) - (Get-Date "1/1/1970")).TotalSeconds
that gives you a double that you can format as you like. This will give nanosecond precision:
"{0:F06}" -f $utime
Update: It's important to note that I don't think Get-Date will give you a nanosecond precision of the time. On my machine the nanosecond place value is always 0.
Related
I am looking to convert timestamps such as the following
2019-01-01T02:15:00+00:00
Into Australian Eastern Standard Time in Perl.
I have over 10,000 of these timestamps, any help would be really appreciated
I need to input them into a mysql DB with a format of YYYY-MM-DD hh:mm:ss
You would use the standard Perl module Time::Piece. It provides the standard strptime and strftime functions. The first allows you to parse a timestamp with a template and the second outputs a timestamp based on the same kind of template. To change timezones you would add or subtract the number of seconds difference.
$t = Time::Piece->strptime("2020-11-04T01:46:00", "%Y-%m-%dT%H:%M:%S");
$t += $offset;
print $t->strftime("%Y-%m-%dT%H:%M:%S");
Or if your current time is the current locale and you're always converting from GMT:
$t = Time::Piece->strptime("2020-11-04T01:46:00", "%Y-%m-%dT%H:%M:%S");
$l = localtime $t->epoch;
print $l->strftime("%Y-%m-%dT%H:%M:%S");
Now if you need to do something more complicated than that (daylight savings time, leap seconds), there is the DateTime module but it is correspondingly far more complicated to use.
See also How can I parse dates and convert time zones in Perl?
HTH
With my limited knowledge of Powershell, I'm trying to convert a string in the current from:
2020-01-23 10:06:07
to a datetime object in the timezone Eastern Standard Time. Ultimately I want to be able to format to ISO8601 standard with the correct offset from UTC.
20-01-23T10:06:07-05:00
Is this achievable within powershell? I have looked at ConvertTimeFromUtc however I am struggling to initially specify that the timezone is Eastern Standard Time instead of GMT.
To treat a given nominal date (one that is unspecified with respect to what time zone it relates to) as one in the EST (US Eastern Standard Time) time zone:
That is, convert a date string such as '2020-01-24 03:00:57' into
a [datetimeoffset] instance that represents this unspecified-in-terms-of-time-zone string as a date/time local to the EST (Eastern Standard Time) time zone (possibly with DST (daylight-saving time) offset applied), which can then be formatted in a ISO 8601 format that includes the resulting date's specific UTC offset.
# Construct a nominal [datetime] instance whose .Kind property value is
# Unspecified (which means unspecified with respect to any particular
# time zone), which a cast from a string achieves:
$nominalDate = [datetime] '2020-01-24 03:00:57'
# Determine the target time zone.
# Note: On macOS and Linux, use 'America/New_York' (ICU library IDs).
$tz = [TimeZoneInfo]::FindSystemTimeZoneById('Eastern Standard Time')
# Get the UTC offset for the nominal date (.Kind == Unspecified),
# which is interpreted as local to that time zone.
# The offset is returned as a [timespan] instance that properly reflects
# DST, if the date falls into the DST window of the target time zone.
# If the input date is ambiguous or invalid, standard time is assumed.
$utcOffset = $tz.GetUtcOffset($nominalDate)
# Construct a [datetimeoffset] instance with the UTC offset determined above.
# This in effect creates a date that represents the nominal date in the
# target time zone, using that time zone's DST-appropriate UTC offset.
$dto = [DateTimeOffset]::new($nominalDate.Ticks, $utcOffset)
# Format according to ISO 8601 with UTC offset, but remove the
# fractional-seconds part:
# Note: With the standar "o" format specifier, only [datetimeoffset]
# instances include their UTC offset in the resulting string,
# not [datetime] instances.
$dto.ToString('o') -replace '\.\d+(?=-)'
The above yields '2020-01-24T03:00:57-05:00', as desired.
With a DST-window input date such as '2020-07-24 03:00:57', it would yield
'2020-07-24T03:00:57-04:00' - note how the UTC offset is now one hour less.
See also: The System.DateTime ([datetime], as a PowerShell type literal), System.DateTimeOffset ([datetimeoffset]), and System.TimeZoneInfo ([TimeZoneInfo]) types, and Standard date and time format strings.
The following is a related use case with a different premise:
To translate a given local date into its EST equivalent:
That is, translate a local point in time, such as obtained by Get-Date, into the equivalent time in the EST time zone.
# Start with a local date, in any time zone.
# (A [datetime] instance whose .Kind property value is Local, though
# Unspecified would work the same).
# Alternatively, start with a UTC date (where .Kind is UTC)
$localDate = Get-Date
# Translate it to Eastern Standard time, as a [datetimeoffset] instance.
# Note: Casting $localDate to [datetimeoffset] is crucial to ensure
# that a [datetimeoffset] with the proper UTC offset is returned.
# Without it, you'd get a [datetime] instance that is nominally
# the correct time, but has an Unspecified .Kind value.
# Also, only a [datetimeoffset] instance includes a UTC offset
# when stringified with format string 'o'
$dtoEST = [TimeZoneInfo]::ConvertTimeBySystemTimeZoneId(
[datetimeoffset] $localDate,
'Eastern Standard Time'
)
# Format according to ISO 8601 with UTC offset, but remove the
# fractional-seconds part:
$dtoEST.ToString('o') -replace '\.\d+(?=-)'
The above yields a string such as '2020-01-23T16:44:41-05:00'.
DataTime itself doesn't have info about time zone. If you want to convert UTC date to other zone date you may use ConvertTimeFromUtc as you mentioned. Example:
$DateTime = Get-Date "2020-01-23 10:06:07"
$TimeZone = [TimeZoneInfo]::FindSystemTimeZoneById("Eastern Standard Time")
[TimeZoneInfo]::ConvertTimeFromUtc($DateTime, $TimeZone)
Or you can convert from any time zone. Get time zones:
[TimeZoneInfo]::GetSystemTimeZones() | select Id | sort Id
Convert from one time zone to another:
$DateTime = Get-Date "2020-01-23 10:06:07"
$SourceTimeZone = [TimeZoneInfo]::FindSystemTimeZoneById("Eastern Standard Time")
$DestinationTimeZone = [TimeZoneInfo]::FindSystemTimeZoneById("Azores Standard Time")
[TimeZoneInfo]::ConvertTime($DateTime, $SourceTimeZone, $DestinationTimeZone)
The actual line in the PowerShell script that is desired is:
$tsd = [datetime]::ParseExact($TSDiff,'yyyyMMddhhmmsstt',$null)
But the $TSDiff variable being used has time expressed as, without AM/PM:
20171023212800
This is a 24-hour format where 11 pm is represented by 23. It was retrieved using an FTP request which seems to only return 24 hour format strings without AM/PM.
Breaking this down, the following PowerShell command works:
[datetime]::ParseExact("20171023092800",'yyyyMMddhhmmss',$null)
But the following PowerShell command does not work:
[datetime]::ParseExact("20171023212800",'yyyyMMddhhmmss',$null)
The reason the second line doesn't work is clear; the hour digits are in 24-hour format, as in the $TSDiff listed at the beginning of this post.
Is there a simple way in PowerShell to convert the string 20171023212800 to 20171023092800PM?
From Formatting Dates and Times
[...]
h, %h - The hour in a 12-hour clock. Single-digit hours will not have a leading zero. Specify %h if the format pattern is not combined with other format patterns.
hh - The hour in a 12-hour clock. Single-digit hours will have a leading zero.
H, %H - The hour in a 24-hour clock. Single-digit hours will not have a leading zero. Specify %H if the format pattern is not combined with other format patterns.
HH - The hour in a 24-hour clock. Single-digit hours will have a leading zero.
[...]
While you are converting your datetime string to a 12-hour formatted string with hh in the format specifier, it will convert to a 24-hour string with HH in it like:
[datetime]::ParseExact("20171023212800",'yyyyMMddHHmmss',$null)
Use:
# Method 1. Use HH for 24-hour format like TessellatingHeckler proposes
[datetime]::ParseExact("20171023212800", 'yyyyMMddHHmmss', $null)
# Method 2. If you are not sure your string is
# date, use TryParse with the same format
[datetime]$dirDate = New-Object DateTime
if ([DateTime]::TryParseExact(
'20171023212800',
'yyyyMMddHHmmss',
[System.Globalization.CultureInfo]::InvariantCulture,
[System.Globalization.DateTimeStyles]::None,
[ref]$dirDate))
{
$dirDate
}
I am trying to create a timestamp string in the format:
yyyymmddhhmmssfff
where f is milliseconds.
Example: 20171013180359235
So far I have
[string]$Date = Get-Date -UFormat "%Y%m%d%H%M%S"
With this I get only up to the seconds. I know if I add %l to the end I get a precision of 2 milliseconds, but I am one short. Is there any way to describe how precise I can choose the milliseconds. Thanks
Using the .tostring() method of the datetime object:
(get-date).ToString('yymmddhhmmssfff')
171513121549340
I use this for some of my work (think, naming files): Get-Date -Format 'DyyyyMMddThhmmsstt.fffffff'. The capital D is for Date and the capital T for time. Perhaps this is helpful!
D20171013T101807AM.8629943
I have a file with lines of the form : 1311597859.567497 y_value_to_plot. The first token is time since epoch, i.e. unix time. The user wants to call plot_file.pl with this filename and a timezone specification such as "America/New_York" or "Europe/London". Calling gnuplot on this file with set xdata time; set timefmt "%s" works but it shows the hours in UTC time. But the user would like to see the local time. So for 1311597859.567497, without any timezone changes, gnuplot would show 12:44:19, but if the user specifies America/New_York, he would like to see 08:44:19 in the gnuplot window.
I though a simple fix would be to calculate the offset between utc and the given timezone and subtract that from the token, and then run new plot on this new file.
Hence I was looking for a way to get offset_seconds of UTC from a given timezone in Perl.
By unix time I assume you mean seconds since the epoch in local time and you are trying to convert to seconds since the epoch in UTC.
Consider using a module such as Time::Zone or DateTime::TimeZone (part of DateTime) to help with such a calculation.
For example with Time::Zone:
use Time::Zone;
my $offset_sec = tz_local_offset(); # or tz_offset($tz) if you have the TZ
# in a variable and it is not local
my $time = time(); # realistically it will be the time value you provide in localtime
my $utc_time = $time + $offset_sec;
With DateTime and DateTime::TimeZone:
use DateTime;
use DateTime::TimeZone;
# cache local timezone because determining it can be slow
# if your timezone is user specified get it another way
our $App::LocalTZ = DateTime::TimeZone->new( name => 'local' );
my $tz = DateTime::TimeZone->new( name => $App::LocalTZ );
my $dt = DateTime->now(); # again, time will be whatever you are passing in
# formulated as a DateTime
my $offset = $tz->offset_for_datetime($dt);
Note that using DateTime you can simply convert a DateTime object from local time to UTC time via set_time_zone('UTC') and then format it for gnuplot also.
To do it all by hand, you can format the output of gmtime if you can get to epoch seconds from your local time (perhaps using mktime out of a date/time string).