2016-07-28 18:13:49 +01:00
// /***************************************************************************
2020-02-27 12:31:23 +00:00
// Aaru Data Preservation Suite
2016-07-28 18:13:49 +01:00
// ----------------------------------------------------------------------------
//
// Filename : DateHandlers.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Helpers.
//
// --[ Description ] ----------------------------------------------------------
//
// Convert several timestamp formats to C# DateTime.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
2020-01-03 17:51:29 +00:00
// Copyright © 2011-2020 Natalia Portillo
2016-07-28 18:13:49 +01:00
// ****************************************************************************/
2015-10-05 18:58:13 +01:00
using System ;
2017-06-06 21:23:20 +01:00
using System.Text ;
2020-02-27 00:33:24 +00:00
using Aaru.Console ;
2015-10-05 18:58:13 +01:00
2020-07-20 15:43:52 +01:00
namespace Aaru.Helpers
2015-10-05 18:58:13 +01:00
{
public static class DateHandlers
{
2020-07-20 21:11:31 +01:00
static readonly DateTime _lisaEpoch = new DateTime ( 1901 , 1 , 1 , 0 , 0 , 0 ) ;
static readonly DateTime _macEpoch = new DateTime ( 1904 , 1 , 1 , 0 , 0 , 0 ) ;
static readonly DateTime _unixEpoch = new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 ) ;
2019-11-25 00:54:39 +00:00
/// <summary>Day 0 of Julian Date system</summary>
2020-07-20 21:11:31 +01:00
static readonly DateTime _julianEpoch = new DateTime ( 1858 , 11 , 17 , 0 , 0 , 0 ) ;
static readonly DateTime _amigaEpoch = new DateTime ( 1978 , 1 , 1 , 0 , 0 , 0 ) ;
2015-10-05 18:58:13 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a Macintosh timestamp to a .NET DateTime</summary>
2017-12-23 03:59:48 +00:00
/// <param name="macTimeStamp">Macintosh timestamp (seconds since 1st Jan. 1904)</param>
2017-12-23 03:51:42 +00:00
/// <returns>.NET DateTime</returns>
2020-07-20 21:11:31 +01:00
public static DateTime MacToDateTime ( ulong macTimeStamp ) = > _macEpoch . AddTicks ( ( long ) ( macTimeStamp * 10000000 ) ) ;
2015-10-05 18:58:13 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a Lisa timestamp to a .NET DateTime</summary>
2017-12-23 03:59:48 +00:00
/// <param name="lisaTimeStamp">Lisa timestamp (seconds since 1st Jan. 1901)</param>
2017-12-23 03:51:42 +00:00
/// <returns>.NET DateTime</returns>
2020-07-20 21:11:31 +01:00
public static DateTime LisaToDateTime ( uint lisaTimeStamp ) = > _lisaEpoch . AddSeconds ( lisaTimeStamp ) ;
2015-10-05 18:58:13 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a UNIX timestamp to a .NET DateTime</summary>
2017-12-23 03:59:48 +00:00
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
2017-12-23 03:51:42 +00:00
/// <returns>.NET DateTime</returns>
2020-07-20 21:11:31 +01:00
public static DateTime UnixToDateTime ( int unixTimeStamp ) = > _unixEpoch . AddSeconds ( unixTimeStamp ) ;
2015-10-05 18:58:13 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a UNIX timestamp to a .NET DateTime</summary>
2017-12-23 03:59:48 +00:00
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
2017-12-23 03:51:42 +00:00
/// <returns>.NET DateTime</returns>
2020-07-20 21:11:31 +01:00
public static DateTime UnixToDateTime ( long unixTimeStamp ) = > _unixEpoch . AddSeconds ( unixTimeStamp ) ;
2016-09-02 18:46:55 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a UNIX timestamp to a .NET DateTime</summary>
2017-12-23 03:59:48 +00:00
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
2017-12-23 03:51:42 +00:00
/// <returns>.NET DateTime</returns>
2020-07-20 21:11:31 +01:00
public static DateTime UnixUnsignedToDateTime ( uint unixTimeStamp ) = > _unixEpoch . AddSeconds ( unixTimeStamp ) ;
2015-10-05 18:58:13 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a UNIX timestamp to a .NET DateTime</summary>
2017-12-23 03:51:42 +00:00
/// <param name="seconds">Seconds since 1st Jan. 1970)</param>
/// <param name="nanoseconds">Nanoseconds</param>
/// <returns>.NET DateTime</returns>
2018-12-31 13:17:27 +00:00
public static DateTime UnixUnsignedToDateTime ( uint seconds , uint nanoseconds ) = >
2020-07-20 21:11:31 +01:00
_unixEpoch . AddSeconds ( seconds ) . AddTicks ( ( long ) nanoseconds / 100 ) ;
2016-09-02 06:49:59 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a UNIX timestamp to a .NET DateTime</summary>
2017-12-23 03:59:48 +00:00
/// <param name="unixTimeStamp">UNIX timestamp (seconds since 1st Jan. 1970)</param>
2017-12-23 03:51:42 +00:00
/// <returns>.NET DateTime</returns>
2020-07-20 21:11:31 +01:00
public static DateTime UnixUnsignedToDateTime ( ulong unixTimeStamp ) = > _unixEpoch . AddSeconds ( unixTimeStamp ) ;
2016-09-02 18:46:55 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a High Sierra Format timestamp to a .NET DateTime</summary>
2017-12-23 03:59:48 +00:00
/// <param name="vdDateTime">High Sierra Format timestamp</param>
2017-12-23 03:51:42 +00:00
/// <returns>.NET DateTime</returns>
2017-12-23 03:59:48 +00:00
public static DateTime HighSierraToDateTime ( byte [ ] vdDateTime )
2017-10-08 22:47:09 +01:00
{
byte [ ] isotime = new byte [ 17 ] ;
2017-12-23 03:59:48 +00:00
Array . Copy ( vdDateTime , 0 , isotime , 0 , 16 ) ;
2019-11-25 00:54:39 +00:00
2017-12-23 03:59:48 +00:00
return Iso9660ToDateTime ( isotime ) ;
2017-10-08 22:47:09 +01:00
}
2017-10-13 21:50:10 +01:00
// TODO: Timezone
2019-11-25 00:54:39 +00:00
/// <summary>Converts an ISO9660 timestamp to a .NET DateTime</summary>
2017-12-23 03:59:48 +00:00
/// <param name="vdDateTime">ISO9660 timestamp</param>
2017-12-23 03:51:42 +00:00
/// <returns>.NET DateTime</returns>
2017-12-23 03:59:48 +00:00
public static DateTime Iso9660ToDateTime ( byte [ ] vdDateTime )
2015-10-05 18:58:13 +01:00
{
2018-06-22 08:08:38 +01:00
byte [ ] twocharvalue = new byte [ 2 ] ;
2015-10-05 18:58:13 +01:00
byte [ ] fourcharvalue = new byte [ 4 ] ;
2016-04-19 02:11:47 +01:00
2017-12-23 03:59:48 +00:00
fourcharvalue [ 0 ] = vdDateTime [ 0 ] ;
fourcharvalue [ 1 ] = vdDateTime [ 1 ] ;
fourcharvalue [ 2 ] = vdDateTime [ 2 ] ;
fourcharvalue [ 3 ] = vdDateTime [ 3 ] ;
2019-11-25 00:54:39 +00:00
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "ISO9600ToDateTime handler" , "year = \"{0}\"" ,
2020-02-29 18:03:33 +00:00
StringHandlers . CToString ( fourcharvalue , Encoding . ASCII ) ) ;
2019-11-25 00:54:39 +00:00
if ( ! int . TryParse ( StringHandlers . CToString ( fourcharvalue , Encoding . ASCII ) , out int year ) )
year = 0 ;
2016-04-19 02:11:47 +01:00
2017-12-23 03:59:48 +00:00
twocharvalue [ 0 ] = vdDateTime [ 4 ] ;
twocharvalue [ 1 ] = vdDateTime [ 5 ] ;
2019-11-25 00:54:39 +00:00
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "ISO9600ToDateTime handler" , "month = \"{0}\"" ,
2020-02-29 18:03:33 +00:00
StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) ) ;
2019-11-25 00:54:39 +00:00
if ( ! int . TryParse ( StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) , out int month ) )
month = 0 ;
2016-04-19 02:11:47 +01:00
2017-12-23 03:59:48 +00:00
twocharvalue [ 0 ] = vdDateTime [ 6 ] ;
twocharvalue [ 1 ] = vdDateTime [ 7 ] ;
2019-11-25 00:54:39 +00:00
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "ISO9600ToDateTime handler" , "day = \"{0}\"" ,
2020-02-29 18:03:33 +00:00
StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) ) ;
2019-11-25 00:54:39 +00:00
if ( ! int . TryParse ( StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) , out int day ) )
day = 0 ;
2016-04-19 02:11:47 +01:00
2017-12-23 03:59:48 +00:00
twocharvalue [ 0 ] = vdDateTime [ 8 ] ;
twocharvalue [ 1 ] = vdDateTime [ 9 ] ;
2019-11-25 00:54:39 +00:00
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "ISO9600ToDateTime handler" , "hour = \"{0}\"" ,
2020-02-29 18:03:33 +00:00
StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) ) ;
2019-11-25 00:54:39 +00:00
if ( ! int . TryParse ( StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) , out int hour ) )
hour = 0 ;
2016-04-19 02:11:47 +01:00
2017-12-23 03:59:48 +00:00
twocharvalue [ 0 ] = vdDateTime [ 10 ] ;
twocharvalue [ 1 ] = vdDateTime [ 11 ] ;
2019-11-25 00:54:39 +00:00
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "ISO9600ToDateTime handler" , "minute = \"{0}\"" ,
2020-02-29 18:03:33 +00:00
StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) ) ;
2019-11-25 00:54:39 +00:00
if ( ! int . TryParse ( StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) , out int minute ) )
minute = 0 ;
2016-04-19 02:11:47 +01:00
2017-12-23 03:59:48 +00:00
twocharvalue [ 0 ] = vdDateTime [ 12 ] ;
twocharvalue [ 1 ] = vdDateTime [ 13 ] ;
2019-11-25 00:54:39 +00:00
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "ISO9600ToDateTime handler" , "second = \"{0}\"" ,
2020-02-29 18:03:33 +00:00
StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) ) ;
2019-11-25 00:54:39 +00:00
if ( ! int . TryParse ( StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) , out int second ) )
second = 0 ;
2016-04-19 02:11:47 +01:00
2017-12-23 03:59:48 +00:00
twocharvalue [ 0 ] = vdDateTime [ 14 ] ;
twocharvalue [ 1 ] = vdDateTime [ 15 ] ;
2019-11-25 00:54:39 +00:00
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "ISO9600ToDateTime handler" , "hundredths = \"{0}\"" ,
2020-02-29 18:03:33 +00:00
StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) ) ;
2019-11-25 00:54:39 +00:00
2017-12-24 02:46:53 +00:00
if ( ! int . TryParse ( StringHandlers . CToString ( twocharvalue , Encoding . ASCII ) , out int hundredths ) )
hundredths = 0 ;
2015-10-05 18:58:13 +01:00
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "ISO9600ToDateTime handler" ,
2020-02-29 18:03:33 +00:00
"decodedDT = new DateTime({0}, {1}, {2}, {3}, {4}, {5}, {6}, DateTimeKind.Unspecified);" ,
year , month , day , hour , minute , second , hundredths * 10 ) ;
2019-11-25 00:54:39 +00:00
2020-07-12 21:25:43 +01:00
sbyte difference = ( sbyte ) vdDateTime [ 16 ] ;
2019-11-25 00:54:39 +00:00
var decodedDt = new DateTime ( year , month , day , hour , minute , second , hundredths * 10 ,
DateTimeKind . Unspecified ) ;
2016-04-19 02:11:47 +01:00
2020-07-12 21:25:43 +01:00
// Convert ISO9660 time from GMT to UTC and remove the difference from GMT. Doing the removal first could cause problems if that makes it cross over a leap day, or a leap second
return TimeZoneInfo . ConvertTimeBySystemTimeZoneId ( decodedDt , "GMT" , "UTC" ) . AddMinutes ( difference * - 15 ) ;
2015-10-05 18:58:13 +01:00
}
2019-11-25 00:54:39 +00:00
/// <summary>Converts a VMS timestamp to a .NET DateTime</summary>
2017-12-23 03:51:42 +00:00
/// <param name="vmsDate">VMS timestamp (tenths of microseconds since day 0 of the Julian Date)</param>
/// <returns>.NET DateTime</returns>
/// <remarks>C# works in UTC, VMS on Julian Date, some displacement may occur on disks created outside UTC</remarks>
2017-12-23 03:59:48 +00:00
public static DateTime VmsToDateTime ( ulong vmsDate )
2015-10-05 18:58:13 +01:00
{
double delta = vmsDate * 0.0001 ; // Tenths of microseconds to milliseconds, will lose some detail
2019-11-25 00:54:39 +00:00
2020-07-20 21:11:31 +01:00
return _julianEpoch . AddMilliseconds ( delta ) ;
2015-10-05 18:58:13 +01:00
}
2019-11-25 00:54:39 +00:00
/// <summary>Converts an Amiga timestamp to a .NET DateTime</summary>
2017-12-23 03:51:42 +00:00
/// <param name="days">Days since the 1st Jan. 1978</param>
/// <param name="minutes">Minutes since o'clock</param>
/// <param name="ticks">Ticks</param>
/// <returns>.NET DateTime</returns>
2016-07-28 22:25:26 +01:00
public static DateTime AmigaToDateTime ( uint days , uint minutes , uint ticks )
2015-10-05 18:58:13 +01:00
{
2020-07-20 21:11:31 +01:00
DateTime temp = _amigaEpoch . AddDays ( days ) ;
2015-10-05 18:58:13 +01:00
temp = temp . AddMinutes ( minutes ) ;
2019-11-25 00:54:39 +00:00
2015-10-05 18:58:13 +01:00
return temp . AddMilliseconds ( ticks * 20 ) ;
}
2016-07-31 20:56:53 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts an UCSD Pascal timestamp to a .NET DateTime</summary>
2017-12-23 03:51:42 +00:00
/// <param name="dateRecord">UCSD Pascal timestamp</param>
/// <returns>.NET DateTime</returns>
2017-12-23 03:59:48 +00:00
public static DateTime UcsdPascalToDateTime ( short dateRecord )
2016-07-31 20:56:53 +01:00
{
2018-06-22 08:08:38 +01:00
int year = ( ( dateRecord & 0xFE00 ) > > 9 ) + 1900 ;
int day = ( dateRecord & 0x01F0 ) > > 4 ;
2017-12-20 17:26:28 +00:00
int month = dateRecord & 0x000F ;
2016-07-31 20:56:53 +01:00
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "UCSDPascalToDateTime handler" ,
2020-02-29 18:03:33 +00:00
"dateRecord = 0x{0:X4}, year = {1}, month = {2}, day = {3}" , dateRecord , year ,
month , day ) ;
2019-11-25 00:54:39 +00:00
2016-07-31 20:56:53 +01:00
return new DateTime ( year , month , day ) ;
}
2016-08-07 04:35:32 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a DOS timestamp to a .NET DateTime</summary>
2017-12-23 03:51:42 +00:00
/// <param name="date">Date</param>
/// <param name="time">Time</param>
/// <returns>.NET DateTime</returns>
2017-12-23 03:59:48 +00:00
public static DateTime DosToDateTime ( ushort date , ushort time )
2016-08-07 04:35:32 +01:00
{
2018-06-22 08:08:38 +01:00
int year = ( ( date & 0xFE00 ) > > 9 ) + 1980 ;
int month = ( date & 0x1E0 ) > > 5 ;
int day = date & 0x1F ;
int hour = ( time & 0xF800 ) > > 11 ;
int minute = ( time & 0x7E0 ) > > 5 ;
2016-08-07 04:35:32 +01:00
int second = ( time & 0x1F ) * 2 ;
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "DOSToDateTime handler" , "date = 0x{0:X4}, year = {1}, month = {2}, day = {3}" ,
2020-02-29 18:03:33 +00:00
date , year , month , day ) ;
2019-11-25 00:54:39 +00:00
2020-02-27 23:48:40 +00:00
AaruConsole . DebugWriteLine ( "DOSToDateTime handler" ,
2020-02-29 18:03:33 +00:00
"time = 0x{0:X4}, hour = {1}, minute = {2}, second = {3}" , time , hour , minute ,
second ) ;
2017-07-19 05:19:28 +01:00
DateTime dosdate ;
2019-11-25 00:54:39 +00:00
try
{
dosdate = new DateTime ( year , month , day , hour , minute , second ) ;
}
catch ( ArgumentOutOfRangeException )
{
dosdate = new DateTime ( 1980 , 1 , 1 , 0 , 0 , 0 ) ;
}
2017-07-19 05:19:28 +01:00
return dosdate ;
2016-08-07 04:35:32 +01:00
}
2016-08-26 01:43:15 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a CP/M timestamp to .NET DateTime</summary>
2017-12-23 03:51:42 +00:00
/// <param name="timestamp">CP/M timestamp</param>
/// <returns>.NET DateTime</returns>
2017-12-23 03:59:48 +00:00
public static DateTime CpmToDateTime ( byte [ ] timestamp )
2016-08-26 01:43:15 +01:00
{
2018-06-22 08:08:38 +01:00
ushort days = BitConverter . ToUInt16 ( timestamp , 0 ) ;
int hours = timestamp [ 2 ] ;
int minutes = timestamp [ 3 ] ;
2016-08-26 01:43:15 +01:00
2020-07-20 21:11:31 +01:00
DateTime temp = _amigaEpoch . AddDays ( days ) ;
2016-08-26 01:43:15 +01:00
temp = temp . AddHours ( hours ) ;
temp = temp . AddMinutes ( minutes ) ;
return temp ;
}
2016-09-05 21:22:04 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts an ECMA timestamp to a .NET DateTime</summary>
2017-12-23 03:51:42 +00:00
/// <param name="typeAndTimeZone">Timezone</param>
/// <param name="year">Year</param>
/// <param name="month">Month</param>
/// <param name="day">Day</param>
/// <param name="hour">Hour</param>
/// <param name="minute">Minute</param>
/// <param name="second">Second</param>
/// <param name="centiseconds">Centiseconds</param>
/// <param name="hundredsOfMicroseconds">Hundreds of microseconds</param>
/// <param name="microseconds">Microseconds</param>
/// <returns></returns>
2019-11-25 00:54:39 +00:00
public static DateTime EcmaToDateTime ( ushort typeAndTimeZone , short year , byte month , byte day , byte hour ,
byte minute , byte second , byte centiseconds , byte hundredsOfMicroseconds ,
byte microseconds )
2016-09-15 01:54:13 +01:00
{
byte specification = ( byte ) ( ( typeAndTimeZone & 0xF000 ) > > 12 ) ;
2019-11-25 00:54:39 +00:00
2020-02-29 18:03:33 +00:00
long ticks = ( ( long ) centiseconds * 100000 ) + ( ( long ) hundredsOfMicroseconds * 1000 ) +
( ( long ) microseconds * 10 ) ;
2019-11-25 00:54:39 +00:00
2016-09-15 01:54:13 +01:00
if ( specification = = 0 )
return new DateTime ( year , month , day , hour , minute , second , DateTimeKind . Utc ) . AddTicks ( ticks ) ;
ushort preOffset = ( ushort ) ( typeAndTimeZone & 0xFFF ) ;
2018-06-22 08:08:38 +01:00
short offset ;
2016-09-15 01:54:13 +01:00
2019-11-25 00:54:39 +00:00
if ( ( preOffset & 0x800 ) = = 0x800 )
offset = ( short ) ( preOffset | 0xF000 ) ;
else
offset = ( short ) ( preOffset & 0x7FF ) ;
2016-09-15 01:54:13 +01:00
if ( offset = = - 2047 )
return new DateTime ( year , month , day , hour , minute , second , DateTimeKind . Unspecified ) . AddTicks ( ticks ) ;
2017-09-14 02:01:43 +01:00
2019-11-25 00:54:39 +00:00
if ( offset < - 1440 | |
offset > 1440 )
offset = 0 ;
2016-09-15 01:54:13 +01:00
2019-11-25 00:54:39 +00:00
return new DateTimeOffset ( year , month , day , hour , minute , second , new TimeSpan ( 0 , offset , 0 ) ) .
AddTicks ( ticks ) . DateTime ;
2016-09-15 01:54:13 +01:00
}
2016-09-18 05:09:02 +01:00
2020-07-22 13:20:25 +01:00
/// <summary>Converts a Solaris high resolution timestamp to .NET DateTime</summary>
2017-12-23 03:59:48 +00:00
/// <param name="hrTimeStamp">Solaris high resolution timestamp</param>
2017-12-23 03:51:42 +00:00
/// <returns>.NET DateTime</returns>
2020-07-20 21:11:31 +01:00
public static DateTime UnixHrTimeToDateTime ( ulong hrTimeStamp ) = >
_unixEpoch . AddTicks ( ( long ) ( hrTimeStamp / 100 ) ) ;
2017-08-16 15:45:15 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts an OS-9 timestamp to .NET DateTime</summary>
2017-12-23 03:51:42 +00:00
/// <param name="date">OS-9 timestamp</param>
/// <returns>.NET DateTime</returns>
2017-12-23 03:59:48 +00:00
public static DateTime Os9ToDateTime ( byte [ ] date )
2017-08-16 15:45:15 +01:00
{
2019-11-25 00:54:39 +00:00
if ( date = = null | |
2020-02-29 18:03:33 +00:00
( date . Length ! = 3 & & date . Length ! = 5 ) )
2019-11-25 00:54:39 +00:00
return DateTime . MinValue ;
2017-08-16 15:45:15 +01:00
2017-12-23 03:59:48 +00:00
DateTime os9Date ;
2017-08-16 15:45:15 +01:00
try
{
2019-11-25 00:54:39 +00:00
os9Date = date . Length = = 5 ? new DateTime ( 1900 + date [ 0 ] , date [ 1 ] , date [ 2 ] , date [ 3 ] , date [ 4 ] , 0 )
: new DateTime ( 1900 + date [ 0 ] , date [ 1 ] , date [ 2 ] , 0 , 0 , 0 ) ;
}
catch ( ArgumentOutOfRangeException )
{
os9Date = new DateTime ( 1900 , 0 , 0 , 0 , 0 , 0 ) ;
2017-08-16 15:45:15 +01:00
}
2017-12-23 03:59:48 +00:00
return os9Date ;
2017-08-16 15:45:15 +01:00
}
2017-09-14 02:01:43 +01:00
2019-11-25 00:54:39 +00:00
/// <summary>Converts a LIF timestamp to .NET DateTime</summary>
2017-12-23 03:51:42 +00:00
/// <param name="date">LIF timestamp</param>
/// <returns>.NET DateTime</returns>
2017-09-14 02:01:43 +01:00
public static DateTime LifToDateTime ( byte [ ] date )
{
2019-11-25 00:54:39 +00:00
if ( date = = null | |
date . Length ! = 6 )
return new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 ) ;
2017-09-14 02:01:43 +01:00
return LifToDateTime ( date [ 0 ] , date [ 1 ] , date [ 2 ] , date [ 3 ] , date [ 4 ] , date [ 5 ] ) ;
}
2019-11-25 00:54:39 +00:00
/// <summary>Converts a LIF timestamp to .NET DateTime</summary>
2017-12-23 03:51:42 +00:00
/// <param name="year">Yer</param>
/// <param name="month">Month</param>
/// <param name="day">Day</param>
/// <param name="hour">Hour</param>
/// <param name="minute">Minute</param>
/// <param name="second">Second</param>
/// <returns>.NET DateTime</returns>
2017-09-14 02:01:43 +01:00
public static DateTime LifToDateTime ( byte year , byte month , byte day , byte hour , byte minute , byte second )
{
try
{
2020-02-29 18:03:33 +00:00
int iyear = ( ( year > > 4 ) * 10 ) + ( year & 0xF ) ;
int imonth = ( ( month > > 4 ) * 10 ) + ( month & 0xF ) ;
int iday = ( ( day > > 4 ) * 10 ) + ( day & 0xF ) ;
int iminute = ( ( minute > > 4 ) * 10 ) + ( minute & 0xF ) ;
int ihour = ( ( hour > > 4 ) * 10 ) + ( hour & 0xF ) ;
int isecond = ( ( second > > 4 ) * 10 ) + ( second & 0xF ) ;
2017-09-14 02:01:43 +01:00
2019-11-25 00:54:39 +00:00
if ( iyear > = 70 )
iyear + = 1900 ;
else
iyear + = 2000 ;
2017-09-14 02:01:43 +01:00
return new DateTime ( iyear , imonth , iday , ihour , iminute , isecond ) ;
}
2019-11-25 00:54:39 +00:00
catch ( ArgumentOutOfRangeException )
{
return new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 ) ;
}
2017-09-14 02:01:43 +01:00
}
2015-10-05 18:58:13 +01:00
}
2017-12-19 20:33:03 +00:00
}