Odd Date/Time format - powershell

I have a single program in the Uninstalls registry key with an odd date/time. The value reported is '1533407816', but the actual date is most likely '20180804', which is what all the other Autodesk products installed that day report as.
I am using [datetime]::ParseExact($program.GetValue('InstallDate'),'yyyyMMdd',$null) to convert those dates to a proper DateTime, but not sure what mechanism I need for the odd one. Or if it's even meaningful data.

The value is likely a Unix time stamp, which is the number of seconds that have elapsed since midnight (UTC) of 1 Jan 1970.
You can convert this value to a [datetime] instance in local time as follows:
[DateTimeOffset]::FromUnixTimeSeconds(1533407816).LocalDateTime
To get a UTC [datetime] instance instead, use .UtcDateTime.
Alternatively, work directly with the [System.DateTimeOffset] instance returned by [DateTimeOffset]::FromUnixTimeSeconds().
Note:
Unix time stamps are signed 32-bit integers ([int]) in seconds.
As an aside, this means that the latest date that they can represent is in the year 2038, a limitation known as the Year 2038 problem.
By contrast, [datetime] instances have a resolution of 100 nanoseconds, called ticks, stored in the .Ticks property, whose type is [long] ([System.Int64] a signed 64-bit integer). To manually convert seconds to ticks, multiply them with 10000000L (1e7L).
Simple helper function:
function convertFrom-UnixTime {
param([int] $Value)
[DateTimeOffset]::FromUnixTimeSeconds($Value).LocalDateTime
}
In action, in the Eastern Time Zone, using the en-US culture:
PS> convertFrom-UnixTime 1533407816
Saturday, August 4, 2018 2:36:56 PM
Expressed in Coordinated Universal Time (UTC) (en-US culture):
PS> (convertFrom-UnixTime 1533407816).ToUniversalTime()
Saturday, August 4, 2018 6:36:56 PM

That odd value to me looks like a Unix Timestamp.
Here's a function that will convert it to a normal date
function ConvertFrom-UnixTimeStamp([Int64]$unixTimeStamp, [switch]$asUtc) {
if ($unixTimeStamp -gt 253402430399) {
Write-Error "Cannot convert $unixTimeStamp to DateTime. Only integer values up to 253402430399 are valid."
}
elseif ($unixTimeStamp -gt [Int32]::MaxValue) {
Write-Warning "The given value exceeds the [Int32]::MaxValue and therefore enters the Year2038 Unix bug.."
}
[DateTime]$origin = New-Object System.DateTime 1970, 1, 1, 0, 0, 0, 0, Utc
if ($asUtc) { return $origin.AddSeconds($unixTimeStamp) }
return ($origin.AddSeconds($unixTimeStamp)).ToLocalTime()
}
ConvertFrom-UnixTimeStamp 1533407816 -asUtc will yield a DateTime object:
Saturday, August 4, 2018 18:36:56

Related

Extract time from date time and find difference between 2 times

I am trying to convert EPOC time to date time and need to extract the time only from that
I am doing below
$min = $Time_Start | measure -Minimum
$max = $Time_End | measure -Maximum
[datetime]$oUNIXDatemin=(Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($min.Minimum))
$oUNIXDatemin_1 = $oUNIXDatemin.ToString("HH:mm:ss")
[datetime]$oUNIXDatemax=(Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($max.Maximum))
$oUNIXDatemax_1 = $oUNIXDatemax.ToString("HH:mm:ss")
Problem is while converting I am getting $oUNIXDatemin_1 and $oUNIXDatemax_1 value like
$oUNIXDatemin_1
12 October 2021 07:46:46
$oUNIXDatemax_1
12 October 2021 21:16:04
My EPOC values are
$min.Minimum
1634024806
$max.Maximum
1634073364
Please let me know what is wrong here. Need to find the difference in HH:mm:ss format.
In PowerShell, you'd usually use a format string. Subtracting two PowerShell datetimes returns a value of type Timespan, which is well-behaved over a span of more than 24 hours.
([datetime]"12 October 2021 21:16:04" - [datetime]"12 October 2021 07:46:46") -f "HH:mm:ss"
13:29:18
Be careful here. Both intervals (durations) and time (of day) have the same format, but different meanings. For example, it makes sense to multiply the interval "01:00:00" (1 hour) by 3 to get three hours; it doesn't make sense to multiply the time "01:00:00" (1 o'clock AM) by 3.
I'm sure the overall calculation can be simplified, but it's too early for me.

Date conversion going wrong with different computer language

I wrote a Powershell script for billing of customers. I get the list of bills, detect the month and get that specific bill. The timestamps are in Unix format and somehow I mess something up in the conversion depending on system language.
For example:
$FirstDayPrevMonth = (get-date -Day 1 -Hour 0 -Minute 0 -second 0 -Millisecond 0).Addmonths(-1)
The conversion fails for systems that return: zondag 1 november 2020 00:00:00. The conversion succeeds for systems that return: Sunday, November 1, 2020 12:00:00 AM
The timestamp I get from the bills list is for example: 1604188800000
The I run the following function passing 1604188800000, which should return number of the month:
Function Convert-FromUnixDateToMonth ($UnixDate) {
(get-date( [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').Addmilliseconds($UnixDate)).ToString("MM/dd/yyyy") ) ) -as [int] ### -UFormat %m
}
The result for the english system is 11 (correct), for the Dutch system is 1 (incorrect). I know it is somewhere in the language setting but I just can't figure out how to change this so it would work independent of the language.
Try below function to convert a Unix timestamp to either Local or UTC DateTime object
function ConvertFrom-UnixTimeStamp([Int64]$UnixTimeStamp, [switch]$AsUTC) {
while ($UnixTimeStamp -lt -62135596800 -or $UnixTimeStamp -gt 253402300799) {
# Assume $UnixTimeStamp to include milli- or nano seconds
$UnixTimeStamp = [int64][math]::Truncate([double]$UnixTimeStamp / 1000)
}
if ($UnixTimeStamp -gt [Int32]::MaxValue) {
# see: https://en.wikipedia.org/wiki/Year_2038_problem
Write-Warning "The given value exceeds the [Int32]::MaxValue of 2147483647 and therefore enters the Year2038 Unix bug.."
}
# the Unix Epoch is January 1, 1970 midnight in UTC
# older PowerShell versions use:
# [DateTime]$epoch = New-Object System.DateTime 1970, 1, 1, 0, 0, 0, 0, Utc
[DateTime]$epoch = [DateTime]::new(1970, 1, 1, 0, 0, 0, 0, 'Utc')
$date = $epoch.AddSeconds($UnixTimeStamp)
if ($AsUTC) { $date } else { $date.ToLocalTime() }
# or use:
# if ($AsUTC) { [DateTimeOffset]::FromUnixTimeSeconds($UnixTimeStamp).UtcDateTime }
# else { [DateTimeOffset]::FromUnixTimeSeconds($UnixTimeStamp).LocalDateTime }
}
For your purposes, get the Month by using it like
(ConvertFrom-UnixTimeStamp 1604188800000).Month
Result on my Dutch system:
11
There is no reason to involve string representations of timestamps; apart from slowing things down, there's the pitfall of culture-specific interpretation, as you've experienced (see next section):
The simplest solution is to use type [datetimeoffset] (System.DateTimeOffset):
# Returns 11 - the month index - in all time zones *at or ahead of* UTC.
[datetimeoffset]::FromUnixTimeMilliseconds(1604188800000).LocalDateTime.Month
A corrected version of your solution attempt:
[timezone]::CurrentTimeZone.ToLocalTime(
([datetime] '1/1/1970').AddMilliSeconds(1604188800000)
).Month
Note that the from-string conversion from '1/1/1970' is unproblematic in this case, due to using a cast.
You didn't need a call to Get-Date at all, which is where the problem arose due to passing a string representation of a date - see next section.
Incidentally, Get-Date -Date directly accepts a [datetime] instance, so there's no need to pass a string.
When you do pass a string, the resulting [datetime] (System.DateTime) has a .Kind property value of Unspecified rather than Local
Specifically, you've run into a problematic inconsistency in from-string type conversions in different contexts:
Casts and script/function parameters use culture-invariant from-string conversion; that is, irrespective of what the current culture is (as reflected in $PSCulture), the rules of the so-called invariant culture are used, whose date formats are based on the US-English culture; therefore, for instance, [datetime] '11/10/2000' is always interpreted as "10 November 2000", i.e., the first token, 11, is interpreted as the month.
However, more international-friendly formats are supported too; e.g.,
[datetime] '2000-11-10' is the equivalent of the above.
Unexpectedly, cmdlet parameters use culture-sensitive from-string conversion.
This discrepancy is a known problem, but it was decided not to fix it, so as not to break backward compatibility - see GitHub issue #3348.

Convert Unix/epoch timestamp to human readable time in Dart Flutter

Say the EPOCH timestamp I received from an API is 1595216214.
It is equivalent to Monday, July 20, 2020 3:36:54 AM (GMT).
My interest is time value only (Ignoring the date/day value)? How can I code in Dart?
Also, how can I convert it into my time zone (E.g.: GMT+8)
you can use DateTime class to do that. Like this:
var dateUtc = DateTime.fromMillisecondsSinceEpoch(myAPIEpochTimeInMilliseconds, isUtc: true);
var dateInMyTimezone = dateUtc.add(Duration(hours: 8));
var secondsOfDay = dateInMyTimezone.hour * 3600 + dateInMyTimezone.minute * 60 + dateInMyTimezone.second;
NOTE:
If you are doing this for the web, although Dart does support 64+ bit numbers, javascript only takes 32-bit integers. So, use the BigInt class for big numbers tha exceeds 32-bit representation.
DateTime doesn't have an inherent timezone to be defined on the class. Is either the local (machine) time or utc Time. So, it is recomended to always use utc and add timezone offset when needed. Or just create a wrapper.

nvd3 (d3.js) date format returns incorrect month

My data looks like this:
[{ x="2013-06-01", y=3}, { x="2013-07-01", y=7 }, { x="2013-08-01", y=3 }]
Chart x-axis is formatted as so:
chart.xAxis
.axisLabel('Date')
.tickFormat(function(d) { return d3.time.format('%b %Y')(new Date(d)); })
;
%b returns May, Jun, July respectively for the dates 2013-06-01, 2013-07-01, 2013-08-01
Why is it returning the previous month, and how can I fix it?
EDIT: If the date is formatted as 2013-06-02, it will return the correct month... does someone know what is happening to cause this?
#Amelia is correct it's because of timezone difference and because Date defaults to 24:00:00 if you don't specify a time. So, in case of EDT, which is -4:00, you lose 4 hours which puts you in the previous day (May 31 2013 20:00:00) and because the days in your dates are 01, this puts you in the previous month.
To bypass this you could append a time to your date if that is allowable in your case.
chart.xAxis
.axisLabel('Date')
.tickFormat(function(d) {
d = d.split('-')
// Create new date by using new Date(year, month, day, hour, second, ms)
// Subtracting 1 is necessary since Javascript months are 0 - 11.
return d3.time.format('%b %Y')(new Date(d[0], +d[1] - 1, d[2], 12, 0, 0));
});
Here is a working Fiddle

UTC Time to String Conversion

I am looking for helping doing time conversions from UTC time to string using MATLAB.
I am trying to extract time from a data file collected at the end of October 2010.
The data file says it is reporting in UTC time and the field is an integer string value in milliseconds that is around 3.02e11. I would like to convert this to a string but am have some trouble.
I figured out that the units are most definitely in milliseconds so I convert this to fractions of days to be compatible with datenum format.
If the data was collected at the end of October (say, October 31, 2010) then I can guess what kind of number I might get. I thought that January 1, 2001 would be a good epoch and calculated what sort of number (in days) I might get:
suspectedDate = datenum('October 31, 2010')
suspectedEpoch = datenum('January 1, 2001')
suspectedTimeInDays = suspectedDate - suspectedEpoch
Which comes out as 3590.
However, my actual time, in days, comes out with the following code
actualTime = 3.02e11
actualTimeInDays = 3.02e11/1000/24/3600
as 3495.4.
This is troubling as the difference is only 94.6 -- not a full year. This would mean either the documentation for the file is wrong or the epoch is close to April 1-5, 2001:
calculatedEpoch = suspectedDate - actualTimeInDays
calculatedEpochStr = datestr(calculatedEpoch)
Alternately, if the epoch is January 1, 2001 then the actual date in the file is from the end of July.
ifEpochIsJanuaryDate = suspectedEpoch + actualTimeInDays
ifEpochIsJanuaryDateStr = datestr(ifEpochIsJanuaryDate)
Is this a known UTC format and can anyone give suggestions on how to get an October date from 3.02e11 magnitude number?
Unix time today is about 13e11, and is measured in ms since 1970.
If your time is ~3e11, then it's probably since year 2000.
>> time_unix = 1339116554872; % example time
>> time_reference = datenum('1970', 'yyyy');
>> time_matlab = time_reference + time_unix / 8.64e7;
>> time_matlab_string = datestr(time_matlab, 'yyyymmdd HH:MM:SS.FFF')
time_matlab_string =
20120608 00:49:14.872
Notes:
1) change 1970 into 2000 if your time is since 2000;
2) See the definition of matlab's time.
3) 8.64e7 is number of milliseconds in a day.
4) Matlab does not apply any time-zone shifts, so the result is the same UTC time.
5) Example for backward transformation:
>> matlab_time = now;
>> unix_time = round(8.64e7 * (matlab_time - datenum('1970', 'yyyy')))
unix_time =
1339118367664
You can't just make up your own epoch. Also datenum returns things in days. So the closeness you got with doing your math was just a coincidence.
Turns out that
>> datenum('Jan-1-0000')
ans =
1
and
>> datenum('Jan-1-0001')
ans =
367
So Matlab should be returning things in days since Jan. 1, 0000. (Not a typo)
However, I'd look carefully at this 3.02e11 number and find out exactly what it means. I'm pretty sure it's not standard Unix UTC, which should be seconds since January 1, 1970. It's way too big. It's close to GMT: Mon, 1 Jan 11540 08:53:20 UTC.