What format does Xamarin store dates in Sqlite? - c#

When saving a standard DateTime from .NET into a SQLite table I get values like this saved:
636183611669074150
What exactly is this format? I am doing some bug fixing and would like to know the exact date held by the number without running my app.

The DateTime.Ticks documentation says:
The value of this property represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 (0:00:00 UTC on January 1, 0001, in the Gregorian calendar).

Related

Convert DateTime to an numerical type format [duplicate]

This question already has answers here:
How to get the unix timestamp in C#
(17 answers)
Closed 8 months ago.
Can somebody help identify the format of this date and time (timestamp). THe webhook I am currently trying to have a link to has a security requirements where I need to get the timestamp. However, the format of the timestamp is new to me. See below the format:
The formatted timestamp converted to string should look like this:
1496734173
I have no idea how do I convert a date and time into something like this. I don't know what this code is or what time does it actually tells.
Click Here for the format
That looks like a pretty standard UNIX epoch timestamp. Assuming we're using the UTC (GMT) timezone, the date is Tuesday, June 6, 2017 7:29:33 AM.
UNIX time is the amount of seconds that have passed since Jan 1, 1970. The timestamp means 1496734173 seconds have passed since then, which is about 47 and a half years, i.e. June 6, 2017.
You can convert a DateTime object to a UNIX timestamp in the following way:
DateTime dateTime = DateTime.Now; // this would be your DateTime
DateTimeOffset offset = new DateTimeOffset(dateTime);
long epoch = offset.ToUnixTimeSeconds(); // our epoch is a 64 bit integer, i.e. long
Or, in one line:
long epoch = new DateTimeOffset(dateTime).ToUnixTimeSeconds();
I think that this represents the UNIX timestamp.
The unix time stamp is a way to track time as a running total of seconds. This count starts at the Unix Epoch on January 1st, 1970 at UTC.
Here you can try and convert your timestamp here: check your time

ConvertTimeFromUtc calculating 00:00:00 for (UTC-07:00) Arizona

I am trying to calculate the time from UTC to a specific timezone. I am using ConvertTimeFromUtc method for this by passing it the specified UTC time and the TimeZoneInfo of the specified timezone display name. This works for multiple timezones however for -7 it is calculating 0 using the following (simplified) parameters:
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("US Mountain Standard Time");
TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse("01/01/0001 05:02:00"), timeZoneInfo)
However after doing the calculation, it comes out as {01/01/0001 00:00:00} which is strange as it works for other timezones such as Minsk etc
Am I missing something?
hum you have UTC-7 so from 01/01/0001 05:02:00 you are in 31/12/0000 22:02:00
(or 12/31/0000 following the US Format)
TimeZoneInfo.ConvertTimeFromUtc(DateTime.Parse("01/01/0001 05:02:00"), timeZoneInfo);
and msdn says:
The DateTime value type represents dates and times with values ranging from 00:00:00 (midnight), January 1, 0001 Anno Domini (Common Era) through 11:59:59 P.M., December 31, 9999 A.D. (C.E.) in the Gregorian calendar.
so 01/01/0001 00:00:00 is the first date available..
you have not missing anything, its just a limit of DateTime
sorry for my english

How to remove time in date time?

How to remove a time in date time ? on column date its only display format
I store the value on repository combobox dropdown, and it store the value including the time. How do I remove the time?
I know there's so many question about this. But the solution was by converting it into a date.tostring("dd MMM yyyy"). Is there a solution beside convert it into string? I want the value was date time not a conversion of string.
The code I am using still giving me a time.
DateTime date = Convert.ToDateTime(gridView1.GetDataRow(i)["date"]);
You just forgot to specify the date at the end of the conversion
DateTime date = Convert.ToDateTime(gridView1.GetDataRow(i)["date"]).Date;
DateTime as the name implify, stores date and time.
You cannot remove time part from date because time is an integral part of date.
To understand this you will have to understand how the date and time are stored. Internally, the date and time is stored as a rational number (in fractions). In computer system 24 hours are considered as numeric 1, so when your value is increased by 1 that means your date is increased by 1 day. If the value is increased by 0.5 that means your date is increased by 12 hours (half day).
So, when you have value 42613.00 that means 31st August at midnight (just when the day started) and if you have value 42613.25 that means 6 AM of 31 Aug 2016 and 42613.50 means 12 noon of 31 Aug 2016 (and 42613.39236 means 9:25:00 AM of 31 Aug 2016)
The smallest fraction of time that need to be stored is 1 millisecond. That means the values of DateTime field should have a precision of more than 0.0000000115740740740741. But this is an irrational value (in binary) and hence cannot be stored as such (the nearest match is 1.00000000000000000000000000110001101101011101010000111010111111..., ... means there are more), so I can say that milliseconds are to their nearest approximation values.
.
That said,
if you wish to take only Date part, you can create your own class or struct to store date part of the DateTime and then override operators for date arithematic and provide implicit conversions to convert them to DateTime if any code that expect DateTime field.

Create Instant using a negative year

I am trying to create an Instant based upon a B.C.E. year in the Gregorian calendar.
Here is what I have so far:
Instant.FromDateTimeOffset(new DateTimeOffset(-1000, 10, 01,
0, 0, 0, 0,
new System.Globalization.GregorianCalendar(),
new TimeSpan()));
I get the error:
An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
Additional information: Year, Month, and Day parameters describe an un-representable DateTime.
Edit
Doing some research on NodaTime, I can see that it does have the ability to represent the dates I want, as it can accept negative ticks from the Unix epoch:
The Noda Time Instant type represents a point on this global timeline: the number of ticks which have elapsed since the Unix epoch. The value can be negative for dates and times before 1970 of course - the range of supported dates is from around 27000 BCE to around 31000 CE in the Gregorian calendar.
- http://nodatime.org/1.3.x/userguide/concepts.html
So I would like to know how to do this using NodaTime rather than create my own implementation, as is mentioned here for instance.
The correct way to create a BCE date in Noda Time is like this:
LocalDate date = new LocalDate(Era.BeforeCommon, 1000, 10, 1);
This gives a LocalDate object, which is representative of just having a date. You asked for an Instant, which represents an exact point in time. These are two very different concepts.
In order to get an Instant from a LocalDate, one has to make a few assertions:
What time of day did it occur?
What time zone was it in?
Is the time valid and unambiguous on that date within that zone?
Let's pick midnight for the time and UTC for the time zone:
Instant instant = date.AtMidnight().InUtc().ToInstant();
Since we chose UTC, we didn't have to address the valid/unambiguous question. With other zones, we would use one of the InZone methods instead of InUtc.
Also - you can indeed create an Instant directly (as Caramiriel showed), but be careful. Year 1 BCE is represented by year 0, so if you want 1000 BCE, you'd have to pass -999, not -1000.
Instant instant = Instant.FromUtc(-999, 10, 1, 0, 0, 0);
Again, this assumes the time at midnight and the UTC time zone.
Finally, keep in mind that none of these calendar systems or time zones actually existed during that time period, and usually when working with dates so old, the time part is not very accurate or relevant. Therefore, I recommend you attempt to only work in terms of LocalDate objects, and not use Instant at all, if you can.

SQLite Date and Time Datatype

I am trying to build a nice, small database to run on a mobile application (Windows Mobile 5, if you are curious).
In the SQLite Documentation, the Date and Time Datatype is defined as follows:
1.2 Date and Time Datatype
SQLite does not have a storage class set aside for storing dates
and/or times. Instead, the built-in Date And Time Functions of SQLite
are capable of storing dates and times as TEXT, REAL, or INTEGER
values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic
Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these
formats and freely convert between formats using the built-in date and
time functions.
So, saving my DateTime value as either a REAL (float) or INTEGER is the same size.
What about the TEXT format? There are 23 characters above in the text YYYY-MM-DD HH:MM:SS.SSS. Is that 8-bytes per character? If so, that is a HUGE waste of space to store in Text format (which is what I am currently doing).
What about the REAL format? Would I define a base date of November 24, 4714 B.C.? (I am not even sure if Visual Studio 2008 will let me do that. I've never tried.) Then get the TimeSpan between base date and date I want, extract the number of days, and store that?
// is this how to declare this date?
private static readonly DateTime nov24_4714bc = new DateTime(-4714, 11, 24);
public static double GetRealDate(DateTime dateTime) {
// FYI: subtracting dates in .NET returns a time span object
return (dateTime - nov24_4714bc).TotalDays;
}
What about the INTEGER format? Would I define a base date of 1970-01-01 00:00:00 UTC (please tell me how to do that!), then get the TimeSpan between base date and my input date, extract the number of seconds, and store that?
// is this a UTC date?
private static readonly DateTime utc1970_01_01 = new DateTime(1970, 1, 1);
public static double GetIntDate(DateTime dateTime) {
// FYI: subtracting dates in .NET returns a time span object
return (dateTime - nov24_4714bc).TotalSeconds;
}
Any help with this? I am a little confused on a few points.
Use the TEXT format if "human-readability" is important.
Use one of the numeric formats if saving space is important.
If you don't need millisecond precision, you can save space in the TEXT format by only including the part you do need. There are 3 shorter formats accepted by SQLite date/time functions:
YYYY-MM-DD HH:MM:SS (19 characters)
YYYY-MM-DD HH:MM (16 characters)
YYYY-MM-DD (10 characters)
(NEVER use MM/DD/YYYY; it's not supported, and it doesn't sort correctly.)
Would I define a base date of November 24, 4714 B.C.? (I am not even
sure if Visual Studio 2008 will let me do that. I've never tried.)
You can't: System.DateTime only supports the years 1 to 9999. You need to pick a different base date, and then do (dateTime - baseDate).TotalDays + baseDateJD, where baseDateJD is the Julian date of the base date. Some reasonable choices are:
0001-01-01 = JD 1721425.5
1970-01-01 = JD 2440587.5
2000-01-01 = JD 2451544.5

Categories

Resources