C# Julian Date Parser - c#

I have a cell in a spreadsheet that is a date object in Excel but becomes a double (something like 39820.0 for 1/7/2009) when it comes out of C1's xls class. I read this is a Julian date format. Can someone tell me how to parse it back into a DateTime in C#?
Update: It looks like I might not have a Julian date, but instead the number of days since Dec 30, 1899.

I think Excel is just using the standard OLE Automation DATE type which can be converted with the DateTime.FromOADate method.
This block of code,
using System;
namespace DateFromDouble
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(DateTime.FromOADate(39820.0));
}
}
}
outputs:
1/7/2009 12:00:00 AM

There's a JulianCalendar class in System.Globalization; Here's how you would use it:
JulianCalendar c = new JulianCalendar();
DateTime time = c.ToDateTime(2009, 1, 7, 0, 0, 0, 0);
Console.WriteLine(time.ToShortDateString());
EDIT:
If it is in fact days since "1900" here's how you can do it:
public static DateTime DaysSince1900(int days)
{
return new DateTime(1900, 1, 1).AddDays(days);
}
DateTime time = DaysSince1900(39820);
Console.WriteLine(time.ToShortDateString()); //will result in "1/9/2009"

That number looks like a 'number of days since 1900' value.

There are two ways to do this CONVERSION --
OLE Automation Date method --
double doubleDate = 43153.0;
DateTime normalDate = DateTime.FromOADate(doubleDate);
/* {2/22/2018 12:00:00 AM} */
DateAdd() Method, using this method, you can specify the kind of date to convert to
double doubleDate = 43153.0;
DateTime normalDate = new DateTime(1899, 12, 30, 0, 0, 0, DateTimeKind.Utc).AddDays(doubleDate);
/* {2/22/2018 12:00:00 AM} */
Note: This date constant {12h December 31, 1899} is called the Dublin Julian Day documented in Julian Day

When dealing with Excel dates, the date may be the string representation of a date, or it may be an OA date. This is an extension method I wrote a while back to help facilitate the date conversion:
/// <summary>
/// Sometimes the date from Excel is a string, other times it is an OA Date:
/// Excel stores date values as a Double representing the number of days from January 1, 1900.
/// Need to use the FromOADate method which takes a Double and converts to a Date.
/// OA = OLE Automation compatible.
/// </summary>
/// <param name="date">a string to parse into a date</param>
/// <returns>a DateTime value; if the string could not be parsed, returns DateTime.MinValue</returns>
public static DateTime ParseExcelDate( this string date )
{
DateTime dt;
if( DateTime.TryParse( date, out dt ) )
{
return dt;
}
double oaDate;
if( double.TryParse( date, out oaDate ) )
{
return DateTime.FromOADate( oaDate );
}
return DateTime.MinValue;
}

Just format the cell(s) in question as Date, use CTRL+1, and select the your desired format.

Related

Convert time string to DateTime in c#

How can I get a DateTime based on a string
e.g:
if I have mytime = "14:00"
How can I get a DateTime object with current date as the date, unless current time already 14:00:01, then the date should be the next day.
This is as simple as parsing a DateTime with an exact format.
Achievable with
var dateStr = "14:00";
var dateTime = DateTime.ParseExact(dateStr, "H:mm", null, System.Globalization.DateTimeStyles.None);
The DateTime.ParseExact() (msdn link) method simply allows you to pass the format string you wish as your parse string to return the DateTime struct. Now the Date porition of this string will be defaulted to todays date when no date part is provided.
To answer the second part
How can I get a DateTime object with current date as the date, unless
current time already 14:00:01, then the date should be the next day.
This is also simple, as we know that the DateTime.ParseExact will return todays date (as we havevnt supplied a date part) we can compare our Parsed date to DateTime.Now. If DateTime.Now is greater than our parsed date we add 1 day to our parsed date.
var dateStr = "14:00";
var now = DateTime.Now;
var dateTime = DateTime.ParseExact(dateStr, "H:mm", null, System.Globalization.DateTimeStyles.None);
if (now > dateTime)
dateTime = dateTime.AddDays(1);
You can use DateTime.TryParse(): which will convert the specified string representation of a date and time to its DateTime equivalent and returns a value that indicates whether the conversion succeeded.
string inTime="14:00";
if(DateTime.TryParse(inTime,out DateTime dTime))
{
Console.WriteLine($"DateTime : {dTime.ToString("dd-MM-yyyy HH:mm:SS")}");
}
Working example here
There is a datetime constructor for
public DateTime(
int year,
int month,
int day,
int hour,
int minute,
int second
)
So then parse the string to find the hours, minutes, and seconds and feed that into this constructor with the other parameters supplied by Datetime.Now.Day and so on.
I think you want to do something like this:
string myTime = "14:00";
var v = myTime.Split(":".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
DateTime obj = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, int.Parse(v[0]), int.Parse(v[1]), DateTime.Now.Second);

GroupWise 2014 Date Format to DateTime

I'm working with the GroupWise 2014 Rest API and I have a problem parsing their date format.
When you fetch a user you receive a json object with "timeCreated": 1419951016000,
But I can't figure out what format that date is.
I've tried
DateTime.Parse
DateTime.FromFileTime
DateTime.FromFileTimeUtc
The value 1419951016000 should be around the time 2014-12-30 15:50
Looks like unix time in milliseconds since January 1st, 1970 at UTC. Current unix time in seconds is shown here as 1419964283.
To convert to a DateTime to unix time, see here: How to convert UNIX timestamp to DateTime and vice versa?. That code works for unix time in seconds; the following works for unix time in milliseconds, represented as a long:
public static class UnixTimeHelper
{
const long MillisecondsToTicks = 10000;
static readonly DateTime utcEpochStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
static DateTime UtcEpochStart { get { return utcEpochStart; }}
public static DateTime ToDateTime(long unixTimeInMs, DateTimeKind kind)
{
var dateTime = UtcEpochStart + new TimeSpan(MillisecondsToTicks * unixTimeInMs);
if (kind == DateTimeKind.Local)
dateTime = dateTime.ToLocalTime();
return dateTime;
}
public static long ToUnixTimeInMs(DateTime dateTime)
{
if (dateTime.Kind == DateTimeKind.Local)
dateTime = dateTime.ToUniversalTime();
var span = dateTime - UtcEpochStart;
return (long)(span.Ticks / MillisecondsToTicks);
}
}
With this code. UnixTimeHelper.ToDateTime(1419951016000, DateTimeKind.Utc).ToString() gives the value "12/30/2014 2:50:16 PM". Is your desired value of "2014-12-30 15:50" in UTC or your local time?
If you are using Json.NET to serialize your JSON, you can write a custom JsonConverter to do the conversion automatically from a DateTime property using the instructions here: Writing a custom Json.NET DateTime Converter . That code also works for unix time in seconds and so will need to be tweaked.
(Finally, seconding Plutonix's suggestion to double-check the documentation. In particular you need to read what the documentation says about the time zone in which the times are returned. It's probably UTC but it pays to make sure.)
Update
After a quick search the online doc looks pretty bad, but this page makes mention of
expiretime
long
Optional. Use an explicit expiration cut-off time. The time is specified as a java long time.
java.util.Date represents "the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT" as a long.

Convert DateTime format to Matlab Date Serial Number format

I want to be able to convert the DateTime (2012/12/31 10-21-17.617) to a decimal number that Matlab takes (Date Serial Number).
I have converted the Matlab date serial number to the Datetime format (yyy/mm/dd HH:mm:ss.fff) by using this:
DateTime conv = new DateTime(1, 1, 1).AddDays(734139.045000000040).AddYears(-1)
However i would like to be able to do the opposite of the above. I know the .NET date starts from 0001/01/01 where as for Matlab it is 0000/00/00.
Unless I'm missing something, a simple approach would be TimeSpan.TotalDays (http://msdn.microsoft.com/en-us/library/system.timespan.totaldays.aspx)
Create a timespan from an arbitrary point to the DateTime you're trying to convert, then adjust as necessary with the offset to get it into matlab format.
Added code example
private DateTime MatlabToNET(double days)
{
return new DateTime(1, 1, 1).AddDays(days).AddYears(-1);
}
private double NETtoMatlab(DateTime dt)
{
TimeSpan ts = dt - new DateTime();
return ts.TotalDays + 365;
}

Adding Seconds to DateTime with a Valid Double Results in ArgumentOutOfRangeException

The following code crashes and burns and I don't understand why:
DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
double d = double.Parse("1332958778172");
Console.Write(dt.AddSeconds(d));
Can someone tell me what's going on? I just can't seem to be able to figure out why...
EDIT
This value comes back from the Salesforce REST API and from what I understand it's a Unix epoch time stamp. "The time of token issue, represented as the number of seconds since the Unix epoch (00:00:00 UTC on 1 January 1970)."
SOLUTION
Salesforce REST API is in fact sending milliseconds back for the issued_at field when performing the OAuth request when they say they're sending seconds...
As others have said, the problem is that the value is too large.
Having looked over it, I believe it represents milliseconds since the Unix epoch, not seconds so you want:
DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
double d = double.Parse("1332958778172"); // Or avoid parsing if possible :)
Console.Write(dt.AddMilliseconds(d));
Either that, or divide by 1000 before calling AddSeconds - but obviously that will lose data.
The value you are adding results in a date outside of the valid range of dates that a DateTime supports.
DateTime supports 01/01/0001 00:00:00 to 31/12/9999 23:59:59.
A simple calculation of 1332958778172/3600/24/365 gives 42267 years.
I think the double value is genuinely too large. It represents just over 42,267 years (if my maths is correct), and DateTime.MaxValue is 23:59:59.9999999, December 31, 9999
DateTime dt = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
Console.Write(dt.AddSeconds(1332958778172D));
Except that...
1332958778172/60/60/24/365 = 42,267 years... which DateTime can only go up to 23:59:59.9999999, December 31, 9999
I had a similar issue where I was required to add a configurable timespan to a datetime.
If the configuration is not correct I have to assume the 'worst scenario' : MaxValue.
I solved it by implementing an extension to DateTime (still in test phase) :
/// <summary>
/// Removes a timespan from a date, returning MinValue or MaxValue instead of throwing exception when if the resulting date
/// is behind the Min/Max values
/// </summary>
/// <returns></returns>
public static DateTime SafeAdd(this DateTime source, TimeSpan value)
{
// Add or remove ?
if (value.Ticks > 0)
{
// add
var maxTicksToAdd = DateTime.MaxValue - source;
if (value.Ticks > maxTicksToAdd.Ticks)
return DateTime.MaxValue;
}
else
{
var maxTicksToRemove = source - DateTime.MinValue;
// get the value to remove in unsigned representation.
// negating MinValues is impossible because it would result in a value bigger than MaxValue : (-32768 .. 0 .. 32767)
var absValue = value == TimeSpan.MinValue ? TimeSpan.MaxValue : -value;
if (absValue.Ticks > maxTicksToRemove.Ticks)
return DateTime.MinValue;
}
return source + value;
}
Looks like this timestamp is in milliseconds, try below code it should work fine.
DateTime nDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
double epoch = 1585008000000;
DateTime rDate = nDateTime.AddMilliseconds(epoch);
In my case I had to consume an api object as a double and convert the unix time to a DateTime:
DateTime Date = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(Double.Parse("1596225600000"));

How to convert javascript numeric date into C# date (using C#, not javascript!)

I'm scraping a website and in the html it has a date in the following format:
"date":"\/Date(1184050800000-0700)\/"
If this was in javascript, it would be a date object and I could use its methods to retrieve the data in whatever format I like. However, I'm scraping it in a C# app. Does anyone know what this format is? Is it the total number of seconds after a certain date or something? I need a way to convert this to a C# datetime object.
If I'm not mistaken, that is a Unix timestamp in milliseconds. 1184050800000 is the timestamp itself, and -0700 is the time zone. This epoch convertor confirms.
Here is some code I've used before for converting Unix timestamps into DateTimes. Be sure to include only the part before -0700:
/// <summary>
/// Converts a Unix timestamp into a System.DateTime
/// </summary>
/// <param name="timestamp">The Unix timestamp in milliseconds to convert, as a double</param>
/// <returns>DateTime obtained through conversion</returns>
public static DateTime ConvertFromUnixTimestamp(double timestamp)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
return origin.AddSeconds(timestamp / 1000); // convert from milliseconds to seconds
}
If you encounter Unix timestamps that are in seconds, you just have to remove the / 1000 part of the last line of the code.
As sinelaw says it seems to be a regex of some sort, however I tried parsing out the numeric values:
1184050800000-0700
And they seem to correspond to:
1184050800000 - Unix timestamp in milliseconds
-0700 - this would be the timezone offset UTC-07:00
You could parse it (I assume it's a string from a JSON object) and convert it to a DateTime like this:
string dateString = "/Date(1184050800000-0700)/";
Regex re = new Regex(#"(\d+)([-+]\d{4})");
Match match = re.Match(dateString);
long timestamp = Convert.ToInt64(match.Groups[1].Value);
int offset = Convert.ToInt32(match.Groups[2].Value) / 100;
DateTime date = new DateTime(1970, 1, 1).AddMilliseconds(timestamp).AddHours(-offset);
Console.WriteLine(date); // 7/10/2007 2:00:00 PM
Am I wrong? It looks like a regexp to me, not a date object at all.
DateTime now = new DateTime(1184050800000);
Console.WriteLine(now); // 2/01/0001 8:53:25 AM
Could this be correct if you aren't interested in the year?

Categories