I am trying to convert to Julian Time Stamp to Date Time. I have the following microseconds time stamp 212302469304212709. As i understand i need to add these milliseconds to the beginning of Julian Calendar (January 1, 4713 B.C., 12:00 (noon)). So i have the following method:
private DateTime GetDateTime(string julianTimeStamp)
{
var julianMilliseconds = Convert.ToDouble(julianTimeStamp)/1000;
var beginningOfTimes = new DateTime(1, 1, 1, 0, 0, 0, 0);
var dateTime = beginningOfTimes.AddMilliseconds(julianMilliseconds).AddYears(-4713).AddMonths(-1).AddDays(-1).AddHours(-12);
return dateTime;
}
Assume i pass 212302469304212709 string as the parameter. The expected result should be 2015/07(July)/01 00:08:24.212. Based on my method, i have almost the same result, but day is not 1, it is 6. Same problem for different time stamps i tested.
Could any one tell me what i am doing wrong? Thanks in advance.
Edited:
This is the exact date time i expect to receive: 2015(year) 7(month) 1(day) 0(hour) 8(minute) 24(second) 212(millisecond) 709(microsecond)
The given timestamp 212,302,469,304,212,709 μs when converted to days (just divide by 86,400,000,000) gives 2457204.505836 days (to six decimal places, which is the best I can do without a lot of extra trouble). Using the Multi Year Computer Interactive Almanac (MICA) written by the United States Naval Observatory, and putting in the free form date 2015(year) 7(month) 1(day) 0(hour) 8(minute) 24(second) 212(millisecond) 709(microsecond), the program calculates exactly the same day count (to six decimal places), proving the time stamp is an accurate Julian date.
One problem with the OP's calculation is trying to use the DateTime class before the earliest supported date, as pointed out by another poster. Also, the OP didn't say if 1 July 2015 was in the Julian or Gregorian calendar, but the MICA calculation proves it is in the Gregorian calendar. Since the OP is working in the Gregorian calendar, the epoch of Julian dates should be stated in the Gregorian proleptic calendar: Noon Universal Time, November 24, 4714 BC. The oft-quoted date January 1, 4713 BC is a proleptic Julian calendar date.
"Proleptic" means a date has been found by beginning at a modern date, who's calendar date is known with absolute certainty, and applying the rules of the chosen calendar backward until the desired date is reached, even though the desired date is before the chosen calendar was invented.
DateTime uses Gregorian calendar, so when you substract years, months and so on you are doing it with that calendar, not the Julian.
Unfortunately DateTime does not support dates before year 1. You can check the library in this post, maybe it helps you.
Related
This question already has answers here:
How do you convert epoch time in C#?
(14 answers)
Closed 2 years ago.
I have a simple DateTime object, equal to the date: 11/1/2020 8:11:14 AM.
I want to convert it to milliseconds so I do:
myTimestamp?.Ticks / TimeSpan.TicksPerMillisecond.
I get 63739786274788, which seems correct from the pure calculation perspective.
However, when I input it into one of the online converters to validate, I get the date Wed Nov 01 3989 01:11:14, which is of course way off.
Questions:
What is this number 63739786274788 if not time in ms?
How do I get "normal" timestamp in ms?
In .NET, DateTime ticks are based on an epoch of 0001-01-01T00:00:00.0000000. The .Kind property is used to decide whether that is UTC, local time, or "unspecified".
Most online converters, such as the one you linked to, are expecting a Unix Timestamp, where the value is based on an epoch of 1970-01-01T00:00:00.000Z. It is always UTC based. (The precision varies, both seconds and milliseconds are commonly used.)
If you want to get a milliseconds-based Unix Timestamp From .NET, instead of dividing you should use the built-in functions DateTimeOffset.FromUnixTimeMilliseconds and DateTimeOffset.ToUnixTimeMilliseconds. (There are also seconds-based versions of these functions.)
Assuming your input values are UTC-based:
DateTime dt = new DateTime(2020, 11, 1, 8, 11, 14, DateTimeKind.Utc);
DateTimeOffset dto = new DateTimeOffset(dt);
long timestamp = dto.ToUnixTimeMilliseconds();
// output: 1604218274000
DateTimeKind.Local will also work with this, assuming your values are indeed based on the computer's local time zone. DateTimeKind.Unspecified is a bit trickier, as you'll need to convert to a DateTimeOffset with a specific time zone using TimeZoneInfo first.
You could also construct the DateTimeOffset value directly, rather than go through DateTime at all.
Okay, so you start off dividing Ticks by TicksPerMillisecond (10,000)
As you can see, the number you generated is much larger than the current milliseconds:
63739786274788
1607363529803
The short answer is that Ticks are based off of 12:00:00 midnight January 1, 0001 and a your online calculator is based off of unix time, January 1, 1970. So that would explain why you're about 2,000 years off. If you subtracted the Ticks from a new DateTime(1970,1,1), then that would give you about the right number to satisfy the online calculator.
For more info, I would suggest reading through MS's docs on DateTime
Today is 1397/02/29 (yyyy/mm/dd) in Persian calendar.
and my website reports his error:
'Year, Month, and Day parameters describe an un-representable DateTime.'
I used datetime2 in SQL database and saved Persian date in it by converting this date:
PersianCalendar pc = new PersianCalendar();
DateTime dateTime = DateTime.Now;
return new DateTime(pc.GetYear(dateTime), pc.GetMonth(dateTime), pc.GetDayOfMonth(dateTime), pc.GetHour(dateTime), pc.GetMinute(dateTime), pc.GetSecond(dateTime), 0);
What should i do?
Quite ignorant here... but in general you should treat "internally" (in the program and in the db) all the dates using the normal Proleptic Gregorian calendar (per ISO 8601), and reformat them to Persian only when you read input from the user/write output to the user. There is a PersianCalendar class in .NET that helps converting persian-to-american and back.
For example
var pc = new PersianCalendar();
DateTime dt = pc.ToDateTime(1397, 02, 29, 0, 0, 0, 0);
works correctly, but if you take a look at the dt variable you'll see that it shows as 2018-05-19.
If doing a ToString() on a DateTime variable you see a persian date, then you probably have an error in your code. If doing a SELECT on a table in the db you see a persian date, then you probably have an error in your db.
The interesting paradox is that internally both .NET and SQL save dates as a single number, representing how many units of time (where in .NET a unit of time is 100 nanoseconds, in SQL it is 1 day) have passed from a "zero point" to the date, but then all their "standard" methods for handling dates (both in .NET and SQL) use the gregorian calendar (because it is the most used in the world).
Use this solution
static void Main(string[] args)
{
Console.WriteLine(GetIsLeapDateTime(1358));
Console.WriteLine(GetIsLeapDateTime(1359));
Console.WriteLine(GetIsLeapDateTime(1360));
Console.WriteLine(GetIsLeapDateTime(1361));
Console.WriteLine(GetIsLeapDateTime(1362));
Console.WriteLine(GetIsLeapDateTime(1363));
Console.WriteLine(GetIsLeapDateTime(1364));
Console.WriteLine(GetIsLeapDateTime(1365));
Console.WriteLine(GetIsLeapDateTime(1366));
Console.ReadLine();
}
private static bool GetIsLeapDateTime(int year)
{
PersianCalendar pc = new PersianCalendar();
return pc.IsLeapYear(year);
}
in Jalali calendar
It seems that every 33 years, leap years happen once every 5 years and then back to once every 4 years.
1370 is a leap year, but 1374 is not a leap year, and instead, 1375 is a leap year. Also, 1403 is not a leap year and 1407 is not a leap year, and instead, 1408 leap years.
I cannot understand or find any information that could explain why there are two different time component output (12p.m and 11 a.m) for the following. Can somebody please explain.
DateTime d1 = new DateTime(2015, 05, 15).ToUniversalTime();
DateTime d2 = new DateTime(2015, 02, 02).ToUniversalTime();
Console.WriteLine(d1.ToString()); //OUTPUTS - 1/05/2015 12:00:00 p.m.
Console.WriteLine(d2.ToString()); //OUTPUTS - 1/02/2015 11:00:00 a.m.
The ToUniveralTime method converts from the local time zone where the code is running, to UTC.
Since time zones can change their offsets from UTC at different times of the year, the value can easily be different between two different dates - especially since one date is in the winter, and the other is in the summer, due to daylight saving time.
See also, the DST tag wiki, and "time zone != offset" in the timezone tag wiki.
I have two dates
DateTime date1Z = DateTime.Parse("2014-05-22 23:39:29Z");
DateTime date1ZKind = DateTime.SpecifyKind(DateTime.Parse("2014-05-22 23:39:29Z"), DateTimeKind.Utc);
DateTime date2 = DateTime.Parse("2014-05-22 23:39:29");
DateTime date2Kind = DateTime.SpecifyKind(DateTime.Parse("2014-05-22 23:39:29"), DateTimeKind.Utc);
Console.WriteLine(date1Z);
Console.WriteLine(date1ZKind);
Console.WriteLine(date2);
Console.WriteLine(date2Kind);
Prints
23/05/2014 11:39:29 a.m.
23/05/2014 11:39:29 a.m.
22/05/2014 11:39:29 p.m.
22/05/2014 11:39:29 p.m.
Can someone explain whats going on here?
Using the suffix "Z" is date shorthand for saying that the Date-Time is "Zulu" time which is another word for UTC time. The first two dates are being parsed as UTC, while the last two are being parsed as whatever time is on the computer in question.
So to answer you question of what is going on: the latter two dates are being offset by your local time, which is apparently +12:00 (plus twelve hours), while the first two are not (as they are marked as "Zulu" or UTC time).
You live in New Zealand, which is +12 over UTC. That matches the date difference you are experiencing. As mentioned, the Z stands for UTC.
I am looking for a way to correctly display localized duration of time larger than 24 hours in C# and Delphi. I mean, the DateTime type often has such string function provided, but time span does not, why?
And I don't even know what is a correct format for non localized time span.
e.g. for a duration of 2 days 10 hours 30 minutes.
I found some would display such time span as 2.10:30:00 or 2:10:30:00 or 2 10:30:00.
Please help, thanks.
For invariant culture (non localized):
myDateTime.ToString(CultureInfo.InvariantCulture)
Otherwise, just use myDateTime.ToShortDateString() or .ToLongDateString().. it will use :
System.Threading.Thread.CurrentThread.CurrentUICulture in that case..
or if you had something specific in mind, you could do
var myCulture = CultureInfo.GetCultureInfo("en-GB");
dt.ToString(myCulture);
EDIT
For TimeSpans:
Example:
DateTime dt1 = new DateTime(2012, 7, 17, 12, 30, 0);
DateTime dt2 = new DateTime(2012, 7, 18, 14, 40, 0);
TimeSpan ts = dt2 - dt1;
string s = ts.ToString("G", CultureInfo.InvariantCulture);
More examples here: http://msdn.microsoft.com/en-us/library/dd784379.aspx
EDIT 2:
More info on TimeSpan format strings:
http://msdn.microsoft.com/en-us/library/ee372286.aspx
You could follow ISO 8601, a PDF of the spec can be found here. See section 4.4.3 Duration
However, using the convention as lined out in this document looks fairly complicated to me, because according to this specification, you need to include context about when the time interval takes place:
The duration of a calendar year, a calendar month, a calendar week or
a calendar day depends on its position in the calendar. Therefore,
the exact duration of a nominal duration can only be evaluated if the
duration of the calendar years, calendar months, calendar weeks or
calendar days used are known.
If the actual moment at which the time span takes place is not relevant for your application, then maybe it would be good enough to forget about the year and month parts and just stick with the format nnDTnnHnnMnnS. That should not be too hard to achieve using the standard TimeSpan methods.
Update:
Reading a bit further, this standard does not seem to be applicable to your problem after all:
Duration is used as a component in representations of time intervals
and recurring time intervals, representation of duration as such is
not facilitated by this International Standard.
I will just leave the answer here to avoid anybody else walking into this dead end like I did, or if you think 'sort of following a standard' is good enough...