I am getting a date from API response as:
string jsonResponse = #"{'endDate': '/Date(-62135578800000-0500)/'}";
Now when I deserialize the reponse using NewtonSoft.json I get the result as:
MyClass obj = JsonConvert.DeserializeObject<MyClass>(jsonResponse);
Console.WriteLine(obj.endDate); // 1/1/0001 5:00:00 AM
Now again after some operation I have to post the data to the server in that same format of the date I have received:
DateTime endDateValue = new DateTime();
endDateValue = obj.endDate
MyClass objNew = new MyClass{
endDate = endDateValue
};
string jsonPostData = JsonConvert.SerializeObject(objNew);
string response = JsonConvert.SerializeObject(jsonPostData);
Console.WriteLine(response);//{"endDate":"0001-01-01T05:00:00+00:00"}
Since I don't want this format "0001-01-01T05:00:00+00:00". It should be same as '/Date(-62135578800000-0500)/'.
Till now I followed this link to understand the type of format:
PHP date format /Date(1365004652303-0500)/
I am able to get the timestamp like this:
DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
long unixTimeStampInTicks = (endDateValue.ToUniversalTime() - unixStart).Ticks;
Console.WriteLine(unixTimeStampInTicks/10000);//-62135578800000
Is there any method in c# to get the offset value -0500 present in this date object like in javascript getTimezoneOffset() method returns the offset.
Simply use DateTimeOffset, not DateTime - it's a similar structure, only with an explicit Offset property. Plain DateTime doesn't have a concept of time zones.
This means using it within MyClass, and deserializing to it.
Related
Assume there's a table with a datetime column represented as ISO string. The datetime data is initially represented as NodaTime ZonedDateTime format in EST. and then it's converted to string format as 2021-02-10T02:07:07.000 -05 For example:
// datetime data represented as ZonedDateTime
var dateTimeUtc = new DateTime(2021, 2, 10, ,7, 7, 7, DateTimeKind.Utc);
var instant = Instant.FromDateTimeUtc(dateTimeUtc);
var zonedDateTime = instant.InZoneNewYork();
// convert datetime value to ISO string
var IsoString = zonedDateTime.Value.ToString("yyyy-MM-ddTHH:mm:ss;fff +o<HH>", CultureInfo.InvariantCulture);
Now I need to retrieve this value from table and represent it in ZonedDateTime EST format.
If I want to get this value from the this table, I can do something like:
var parsePattern = ZonedDateTimePattern.CreateWithInvariantCulture("yyyy-MM-ddTHH:mm:ss;fff +O<HH>", DateTimeZoneProviders.Tzdb);
However the returned string is represented as UTC time 2021-02-10T02:07:07 UTC (+00) which is not accurate (the actual saved value is EST).
Is there a way I can read ISO string with a specified time zone using NodaTime?
Is there a way I can read ISO string with a specified time zone using
NodaTime?
Changing format of ZonedDateTime Iso string representation, and preserving that format for both conversion operations should help.
Change "yyyy-MM-ddTHH:mm:ss;fff +O<HH>" to ZonedDateTimePattern.GeneralFormatOnlyIso.PatternText like:
var dateTimeUtc = new DateTime(2021, 2, 10, 7, 7, 7, DateTimeKind.Utc);
var instant = Instant.FromDateTimeUtc(dateTimeUtc);
DateTimeZone ny = DateTimeZoneProviders.Tzdb["America/New_York"];
var zonedDateTime = instant.InZone(ny);
// convert datetime value to ISO string
var IsoString = zonedDateTime.ToString(ZonedDateTimePattern.GeneralFormatOnlyIso.PatternText,
CultureInfo.InvariantCulture);
//parse iso string, like "2021-02-10T02:07:07 America/New_York (-05)"
var parsePattern = ZonedDateTimePattern.CreateWithInvariantCulture(
ZonedDateTimePattern.GeneralFormatOnlyIso.PatternText,
DateTimeZoneProviders.Tzdb);
var date2 = parsePattern.Parse("2021-02-10T02:07:07 America/New_York (-05)").Value;
I has in string format, timestamp 1593339378252, i need convert this, to a normal human date-20.06.2020
I try this code
var timestamp = Convert.ToInt64(dateFrom);
// Format our new DateTime object to start at the UNIX Epoch
System.DateTime dateTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0);
// Add the timestamp (number of seconds since the Epoch) to be converted
dateTime = dateTime.AddSeconds(timestamp);
but if i try convert to int32,16,64 i get System.ArgumentOutOfRangeException
It seems that your timestamp actually contains number of milliseconds, not seconds:
new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc).AddMilliseconds(1593339378252)
// on my machine - 28-Jun-20 10:16:18 AM
You can use var dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(yourValue);
For more information, also look at the documentation
Attached is a method I am currently using that takes in a list of DateTime strings, their input format (i.e. yyyy-MM-dd HH:mm:ss), and their offset in the form of hours.
As for the culture and "standard", I am using InvariantCulture and I am converting the times to UTC.
public int unixFormat3(string dateTimeInput, string inputFormat, int hours)
{
DateTime result;
CultureInfo provider = CultureInfo.InvariantCulture;
result = DateTime.ParseExact(dateTimeInput, inputFormat, provider);
int unixTime = (Int32)(result.ToUniversalTime().AddHours(hours).Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc))).TotalSeconds;
return unixTime;
}
Two issues with said method:
I am using this website as a comparison. If my input is 2014-03-18 21:00:00, my output, according to my method, is 1395190800, which converts back to 2014-03-19 01:00:00. It has a four hour difference. The desired output is this:
If my input is 2014-03-18 24:00:00, I get this error:
The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar.
Noticeably, it does not allow the input of 24 in the HH part. This is a weird error as NodaTime handles it just fine... Though that's irrelevant as I am using DateTime.
Does anyone have any insight on this area?
EDIT:
Upon some experimentation, removing the .ToUniversalTime() removes my 4-hour offset.. Why is this happening?
public int unixFormat3(string dateTimeInput, string inputFormat, int hours)
{
DateTime result;
CultureInfo provider = CultureInfo.InvariantCulture;
result = DateTime.ParseExact(dateTimeInput, inputFormat, provider);
int unixTime = (Int32)(result.AddHours(hours).Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc))).TotalSeconds;
return unixTime;
}
This document, http://www.w3.org/TR/NOTE-datetime, cited in this question How to know whether a given string is a valid UTC DateTime format? does not list 24 as a valid hour value.
This document, http://en.wikipedia.org/wiki/Iso8601, cited by an answer to the question does list 24:00 as a valid time. This one, http://en.wikipedia.org/wiki/12-hour_clock#Confusion_at_noon_and_midnight, also says 24:00 is valid.
The System.DateTime object represents hours as an integer value between 0 and 23 (see http://msdn.microsoft.com/en-us/library/vstudio/system.datetime.hour(v=vs.100).aspx). As far as I know, NodaTime doesn't use any of the .NET provided DateTime or DateTimeOffset classes and handles everything itself, which is why it's handling an hour of 24 correctly.
As for why ToUniversalTime() is adding an offset, its probably because the ParseExact is returning a date that's already been adjusted. (What is the value of result just before you call ToUniversalTime()?)
You may also want to change your call to use this overload of ParseExact instead:
result = DateTime.ParseExact(dateTimeInput, inputFormat, provider, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
This tells the parser to assume the time is in UTC if no time zone is specified in the parsed string.
As a side note, you should probably declare your Unix epoch as a readonly global variable somewhere and use TryParseExact instead of ParseExact.
public class UnixTime
{
public static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
public int unixFormat3(string dateTimeInput, string inputFormat, int hours)
{
int unixTime = -1;
DateTime result = DateTime.MinValue;
if (DateTime.TryParseExact(dateTimeInput, inputFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out result))
{
unixTime = (int)(result.AddHours(hours).Subtract(UnixTime.Epoch)).TotalSeconds;
}
return unixTime;
}
}
I am getting date from javascript to c# in this format "/Date(1330540200000)/"
I want to convert this "/Date(1330540200000)/" format to MM:dd:yyyy format in c#.
I am able to convert it in javascript but here I want to convert this in c#.
There is a lot of javascript components that sends a a timestamp information as date. You can use a function like this:
public static DateTime ConvertTimeStampToDateTime(double value)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0); //Unix Epoch on January 1st, 1970
return origin.AddMilliseconds(value);
}
After you've got the DateTime structure, you could use ToString(string format) to format as you want into a string, for sample:
// a string timeStamp (for sample, in string).
string timeStampString = "1330540200000";
// pass as a double, convert it if it is a string.
DateTime myDate = ConvertTimeStampToDateTime(double.Parse(timeStampString));
string myDateFormated = myDate.ToString("MM:dd:yyyy");
you can try this:
public static string ParseFromString(string dateTime){
return new DateTime(1970,1,1).AddMilliseconds(double.Parse(Regex.Match ("/Date(1330540200000)/", #"(\d+)").Value)).ToString("MM:dd:yyyy");
}
I want to convert 18 digit string from LDAP AccountExpires to Normal Date Time Format.
129508380000000000 >> May 26 2011
I got the above conversion from using the following link.
http://www.chrisnowell.com/information_security_tools/date_converter/Windows_active_directory_date_converter.asp?pwdLastSet,%20accountExpires,%20lastLogonTimestamp,%20lastLogon,%20and%20badPasswordTime
I tried to convert by using DateTime.Parse or Convert.ToDateTime. But no success.
Anyone know how to convert it? Thanks very much.
Edited answer
It's the number of ticks since Jan-01-1601 in UTC, according to Reference, which describes the significance of the year 1601. Good background reading.
var accountExpires = 129508380000000000;
var dt = new DateTime(1601, 01, 01, 0, 0, 0, DateTimeKind.Utc).AddTicks(accountExpires);
Original Accepted Answer
It's the number of ticks since Jan-02-1601.
DateTime dt = new DateTime(1601, 01, 02).AddTicks(129508380000000000);
You can use the FromFileTime method on the DateTime class, but watch out, when this field is set to not expire, it comes back as the Int64.MaxValue and doesn't work with either of these methods.
Int64 accountExpires = 129508380000000000;
DateTime expireDate = DateTime.MaxValue;
if (!accountExpires.Equals(Int64.MaxValue))
expireDate = DateTime.FromFileTime(accountExpires);
Some info for anyone who came here looking to set the AccountExpires value.
To clear the expiry is nice and easy:
entry.Properties["accountExpires"].Value = 0;
However if you try to directly write back an int64 / long:
entry.Properties["accountExpires"].Value = dt.ToFileTime();
You can get a 'COMException was unhandled - Unspecified error'
Instead write back the value as a string data type:
entry.Properties["accountExpires"].Value = dt.ToFileTime().ToString();
Be aware of the time of day you are setting, for consistancy with ADUC the time should be 00:00.
Instead of .Now or .UtcNow you can use .Today:
var dt1 = DateTime.Today.AddDays(90);
entry.Properties["accountExpires"].Value = dt1.ToFileTime().ToString();
Other input like dateTimePicker you can replace the time, Kind as Local for the Domain Controller:
var dt1 = dateTimePicker1.Value;
var dt2 = new DateTime(dt1.Year, dt1.Month, dt1.Day, 0, 0, 0, DateTimeKind.Local);
entry.Properties["accountExpires"].Value = dt2.ToFileTime().ToString();
If you View Source on the link you posted you should see a Javascript conversion algorithm that should translate quite nicely to c#
For Ruby
def ldapTimeConverter(ldap_time)
Time.at((ldap_time/10000000)-11644473600)
end
I stumbled across this working on a PowerShell script. I found I can query the accountexpirationdate property and no conversion is required.
Someone had the "best" way above but when it's set to never expired, the value is zero.
public static DateTime GetAccountExpiresDate(DirectoryEntry de)
{
long expires = de.properties["accountExpires"].Value;
if (expires == 0) // doesn't expire
return DateTime.MaxValue;
return DateTime.FromFileTime(expires);
}
I'll provide a perfect answer to this question using which you will be able to convert and DateTime to active directory long int format and will be also able to do the vice versa of it.
Here is a solution to it:-
To get DateTime from AD
string tickstring = de.Properties["accountExpires"][0].ToString();
long Ticks = (long) tickstring;
DateTime ReferenceDate = new DateTime(1601, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long ExpireDateTicks = Ticks + ReferenceDate.Ticks;
DateTime ExpireDate = new DateTime(ExpireDateTicks);
To convert DateTime to AD long integer format
DateTime ReferenceDate = new DateTime(1601, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime ExpireDate = new DateTime(Request.EndDate.Year, Request.EndDate.Month, Request.EndDate.Day, 0, 0, 0);
long Ticks = ExpireDate.Ticks - ReferenceDate.Ticks;
NewUser.accountExpires = Ticks.ToString();