C# query datetime off sqlite database fails - c#

I am reading a sqlite file in which datetime column data are saved as integer values (INTEGER NO NULL)
DateTime dt=reader.GetDateTime(nColDateTime);
But it emits an error saying that the return value is not in correct format.
I try out all other available methods in Datetime class and find only
DateTime dt=DateTime.FromBinary(reader.GetInt64(nColDateTime));
works (as others return exceptions).
But the formatted date (as dt.ToShortDateTime()) is incorrect (ie 0042/11/20) I have no idea what this is.
I then try this
long d=DateTime.Now.Ticks-reader.GetInt64(nColDateTime);
DateTime dt=new DateTime(d);
It gives me 1970/05/18
Could you help me to get the correct datetime ?

Your dates are stored in the Unix epoch format.
You probably just want to use:
private static readonly DateTime epoch = new DateTime(1970, 1, 1);
...
var myDate = epoch + TimeSpan.FromTicks(reader.GetInt64(nColDateTime));
For example, when I look at your example above "1970/05/18", I can assume that your date is approximately 5 months, 18 days earlier than today.
Here is how I would retreieve the original value:
(DateTime.Today - new DateTime(1970, 5, 18)).Ticks
Which returns:
13119840000000000
Plugging that into my formula:
new DateTime(1970, 1, 1) + TimeSpan.FromTicks(13119840000000000)
This returns:
2011/07/30

Related

How to parse datetime without date in C#?

If I have a string like 15:00 and I parse this to DateTime ot DateTimeOffset, the date is set to today.
I want somehow to distinguish, if the date part is given or not. It would help, if the date part is not given, the date is 1.1.1970.
Is there a better possibility instead of using regex and parse this by my own?
Try to parse the value as TimeSpan and then try to parse it as DateTime.
var data = "15:00";
if (TimeSpan.TryParse(data, out var time))
{
Console.WriteLine("Time: {0}", time);
}
else if (DateTime.TryParse(data, out var datetime))
{
Console.WriteLine("DateTime: {0}", datetime);
}
else
{
Console.WriteLine("I don't know how to parse {0}", data);
}
If I have a string like "15:00" and I parse this to DateTime ot
DateTimeOffset, the date is set to today.
This is by design.
From DateTime.Parse doc:
A string with a time but no date component. The method assumes the
current date unless you call the Parse(String, IFormatProvider,
DateTimeStyles) overload and include
DateTimeStyles.NoCurrentDateDefault in the styles argument, in which
case the method assumes a date of January 1, 0001.
From DateTimeOffset.Parse doc:
If is missing, its default value is the current day.
So, for DateTime, if you don't use any DateTimeStyles, you get the current date
var hours = "15:00";
var date = DateTime.Parse(hours, CultureInfo.InvariantCulture); // 12/9/2018 3:00:00 PM
but if you use DateTimeStyles.NoCurrentDateDefault as a third parameter;
var hours = "15:00";
var date = DateTime.Parse(hours, CultureInfo.InvariantCulture, DateTimeStyles.NoCurrentDateDefault);
// 1/1/0001 3:00:00 PM
But I think your problem keeps on that sentence; "if the date part is given or not.." How did you decide your string has date part or not? Is it always have 5 characters as Steve commented? It can be in a format like 4:00? What about 4:1? If it can be like 4:1, it should be parsed as 4:10 or 4:01?
So, you need to decide first what is the meaning of "if the date part is given or not.." for your case. Then you can easily parse your string to TimeSpan, not DateTime in my opinion, so, you can add it created manually "1.1.1970" with DateTime(int, int, int) constructor.
if(YourConditionForYourStringNotIncludingDatePart)
{
var time = TimeSpan.Parse("15:00");
var date = new DateTime(1970, 1, 1);
var result = date.Add(time);
}
Using regular expressins for DateTime parsing is usually a bad idea. I wouldn't suggest to use it unless you have no other way to do it for DateTime.
I think for that case you could things keep simple. This could be a solution that not depends on the lenght when there is only a timepart:
void Main()
{
Console.WriteLine(ParseWithDummyIfDateAbsent("15:00", new DateTime(1970, 1, 1)));
Console.WriteLine(ParseWithDummyIfDateAbsent("15:00:22", new DateTime(1970, 1, 1)));
Console.WriteLine(ParseWithDummyIfDateAbsent("09.12.2018 15:00", new DateTime(1970, 1, 1)));
}
DateTime ParseWithDummyIfDateAbsent(string input, DateTime dummyDate)
{
if(TimeSpan.TryParse(input, out var timeSpan))
input = $"{dummyDate.Date.ToShortDateString()} {input}";
return DateTime.Parse(input);
}
Output:
01.01.1970 15:00:00
01.01.1970 15:00:22
09.12.2018 15:00:00
Depends on your localization:-)

What are valid UTCDateTime type string formats for AIF transfomrmations?

Im am trying to write a .net class that transforms a piece of xml to a AX UtcDateTime type.
The class is used in an inbound transformation.
Original xml:
<DateTime>
<Date>2014-06-12</Date>
<Time>10:52:00</Time>
<Zone>+02:00</Zone>
</DateTime>
My resulting xml leads to an exeption in the exeptionlog:
"The value '2014-06-12T12:52:00+02:00' is not a valid UtcDateTime type."
I think AIF expect the Z at the end of the value, and I am not sure if the localDateTime is mandatory and or if the milliseconds are a requirement.
I would like to know how the UtcDateTime field in transformed xml should be formatted to be accepted by AIF.
Like so:
<MessageHeaderDateTime localDateTime="2014-06-12T10:52:00+02:00">2014-06-12T08:52:00Z</MessageHeaderDateTime>
or like so:
<MessageHeaderDateTime localDateTime="2014-06-12T10:52:00.1108723+02:00">2014-06-12T08:52:00.1108723Z</MessageHeaderDateTime>
or are other things missing?
My Code
DateTime netdttm = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc);
TimeSpan timespan = new TimeSpan(zhour, zminute, 0);
DateTime netdttmoffset = netdttm.Subtract(timespan);
datetime.Value = netdttmoffset;
datetime.localDateTime = netdttmoffset.ToLocalTime();
datetime.localDateTimeSpecified = true;
I use a similar appraoch for the case where I use utcnow.
Problem i that I have limited testing possibilities due to hot-swapping being disbled in the environment where I have to develop my code. So I would like to be certainin about the formatting.
Thanx for your help.
I finally got it to work. My solution:
//declare the AX utcdatetime type from the cs class generate with:
//xsd C:\...\SharedTypes.xsd C:\..\AIFschema.xsd /Classes /Out:C:\location\of\csfile\
AxType_DateTime datetime = new AxType_DateTime();
//Ax store the time in GMT with an optional local time. My XML can have any timezone.
datetime.timezone = AxdEnum_Timezone.GMT_COORDINATEDUNIVERSALTIME;
//I set this to false as i am not interested in actually storing the local time. Plus AX fails over the formatting .net returns.
datetime.timezoneSpecified = false;
//{... left out code to retrieve the hours, minutes etc from my XML}
//declare the .net datetime variable with the values from the xml:
DateTime netdttm = new DateTime(year, month, day, hour, minute, second, millisecond, DateTimeKind.Utc);
DateTime netdttmoffset = new DateTime();
// (optional field) <zone>+01:00</zone>
if (message.Header.DateTime.Zone != null)
{
{... left out code to retrive zone offset info from xml}
TimeSpan timespan = new TimeSpan(zhour, zminute, 0);
netdttmoffset = netdttm.Subtract(timespan);
}
else //no zone, so datetime == GMT datetime.
{
netdttmoffset = netdttm;
}
datetime.Value = netdttmoffset;
datetime.localDateTime = netdttmoffset.ToLocalTime();
//do not output to xml, or AX will fail over this.
datetime.localDateTimeSpecified = false;
Result xml snippet as accepted by AX:
<MessageHeaderDateTime>2014-07-30T16:41:10.001Z</MessageHeaderDateTime>
I found this to be easier. If you want a particular datetime, say Jan 31, 2015 8:00 am, to be stored in AX, the .net code to make it happen would be
DateTime utcDateTime = new DateTime(2015, 1, 31, 8, 0, 0).ToUniversalTime();
var workerStartDate = new AxdExtType_HcmEmploymentStartDateTime
{
Value = utcDateTime
};
The XML generated would be would be <WorkerStartDate>2015-05-12T13:00:00Z</WorkerStartDate>, assuming you are 5 hours behind GMT on the computer that runs the .net code. The AX database will store the value 2015-05-12T13:00:00Z as well.
<dyn:StartDate>2014-06-22T00:00:00.000+02:00</dyn:StartDate>
This format always does the trick for me. (Notice the ms)

Converting ticks to DateTime

There are a number of questions on this site explaining how to do this. My problem I when I do what seems to work for everyone else I don't get the correct date or time. The code is ...
long numberOfTicks = Convert.ToInt64(callAttribute);
startDateTime = new DateTime(numberOfTicks);
The value of callAttribute is = "1379953111"
After converting it the value of numberOfTicks = 1379953111
But the DateTime ends up being startDateTime = {1/1/0001 12:02:17 AM}
I have taken the same value for ticks and converted it online and it comes up with the correct date/time.
What am I doing wrong?
Your value doesn't seem to be a number of ticks; I suspect it's a UNIX timestamp (number of seconds since 1970/01/01 UTC)
Here's a function to convert from a UNIX timestamp:
static readonly DateTime _unixEpoch =
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static DateTime DateFromTimestamp(long timestamp)
{
return _unixEpoch.AddSeconds(timestamp);
}

Convert datetime from xml datetime to epoch format

I'm feeding an android application with a xml having a datetime attribute.
Problem here is, the application is accepting datetime by 13 digit number like 1347712845061. I'm not able to find an options to do this type of conversion in c#.
Do anyone have any suggestion?
Assuming that sample value was meant to be Sat, 15 Sep 2012 12:40:45 UTC, it just means "number of milliseconds since the Unix epoch". (That's the information within a java.util.Date.) So you can write:
private static readonly DateTime UnixEpoch =
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static DateTime FromJavaDate(long millisSinceEpoch)
{
return UnixEpoch.AddMilliseconds(millisSinceEpoch);
}
(You could use a DateTimeOffset too, which would always have an offset of 0.)

ASP.NET: Get milliseconds since 1/1/1970

I have an ASP.NET, VB.NET Date, and I'm trying to get the number of milliseconds since January 1st, 1970. I tried looking for a method in MSDN, but I couldn't find anything. Does anyone know how to do this?
Starting with .NET 4.6, The method ToUnixTimeMilliseconds provides a more accurate solution.
From DateTimeOffset:
DateTimeOffset.Now.ToUnixTimeMilliseconds()
From DateTime:
new DateTimeOffset(dateTime).ToUnixTimeMilliseconds()
Source: https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tounixtimemilliseconds?view=netframework-4.6#System_DateTimeOffset_ToUnixTimeMilliseconds
You can subtract any two DateTime instances and get TimeSpan and TotalMilliseconds would give you total milliseconds. Sample below.
DateTime dt1970 = new DateTime(1970, 1, 1);
DateTime current = DateTime.Now;//DateTime.UtcNow for unix timestamp
TimeSpan span = current - dt1970;
Console.WriteLine(span.TotalMilliseconds.ToString());
one liner
//DateTime.MinValue is 01/01/01 00:00 so add 1969 years. to get 1/1/1970
DateTime.Now.Subtract(DateTime.MinValue.AddYears(1969)).TotalMilliseconds;
Alternatively, you can use the Ticks property and avoid construction of a temporary object:
long epochTime = (DateTime.UtcNow.Ticks - 621355968000000000) / 10000;
However, this isn't entirely
Reasoning:
DateTime d = new DateTime(1970, 01, 01);
var temp = d.Ticks; // == 621355968000000000
This will provide the UNIX Epoch in milliseconds.
(Respects UTC time instead of your local time)
Split(DateTime.UtcNow.Subtract(DateTime.MinValue.AddYears(1969)).TotalMilliseconds(), ".", 2)(0)

Categories

Resources