reverse timestamp - c#

I was trying to save some stuff to the Log table with timestamp so I first did this:
public static string TimeStamp(
this DateTime datetime, string timestamptFormat = "yyyyMMddHHmmssffff")
{
return datetime.ToString(timestamptFormat);
}
And then I found a snippet like this:
static public string ToReverseTimestamp(this DateTime dateTime)
{
return string.Format("{0:10}", DateTime.MaxValue.Ticks - dateTime.Ticks);
}
I started wondering what the heck is reverse timestamp is useful for, and came across this article
Now my question is: if the second snippet is even correct? And how do you convert it back to "normal" timestamp or how do you get readable datetime information from it?

Make sure that the DateTime is converted to universal time before conversion to avoid time-zone problems:
public static string ToReverseTimestamp(this DateTime dateTime)
{
return (long.MaxValue - dateTime.ToUniversalTime().Ticks).ToString();
}
You can convert the value back to a DateTime value by parsing the string to a long, calculating MaxValue - (MaxValue - x) = x and constructing a new DateTime with DateTimeKind.Utc from x:
public static DateTime FromReverseTimestamp(string timestamp)
{
return new DateTime(long.MaxValue - long.Parse(timestamp), DateTimeKind.Utc);
}
Example:
var input = DateTime.Now; // {17/05/2012 16:03:17} (Local)
var timestamp = ToReverseTimestamp(input); // "2520650302020786038"
var result = FromReverseTimestamp(timestamp); // {17/05/2012 18:03:17} (Utc)

Related

Convert a time in milliseconds to local date string

I am trying to convert a TimeStamp in milliseconds to a local date time. But this is weird.
The date is increased by 1 day. I don't know how stupid may I sound, but I would really be happy to have someone throw light on this.
CODE:
public static DateTime ConvertToLocalDate(string timeInMilliseconds){
double timeInTicks = double.Parse(timeInMilliseconds);
TimeSpan dateTimeSpan = TimeSpan.FromMilliseconds(timeInTicks);
DateTime dateAfterEpoch = new DateTime(1970, 1, 1) + dateTimeSpan;
DateTime dateInLocalTimeFormat = dateAfterEpoch.ToLocalTime();
return dateInLocalTimeFormat;
}
For example, if I pass:
1579631400000 which is equivalent to: 2020-01-21T18:30:00
it returns: 1/22/2020 12:00:00 AM
What is wrong?
Since your ConvertToLocalDate function returns the date and time to your local time zone. You need to convert it to UTC to get the expected date and time.
class Program
{
static void Main(string[] args)
{
Console.WriteLine(ConvertToLocalDate("1579631400000").ToUniversalTime());
Console.ReadKey();
}
public static DateTime ConvertToLocalDate(string timeInMilliseconds)
{
double timeInTicks = double.Parse(timeInMilliseconds);
TimeSpan dateTimeSpan = TimeSpan.FromMilliseconds(timeInTicks);
DateTime dateAfterEpoch = new DateTime(1970, 1, 1) + dateTimeSpan;
DateTime dateInLocalTimeFormat = dateAfterEpoch.ToLocalTime();
return dateInLocalTimeFormat;
}
}
Or simply do not use ToLocalTime() inside your ConvertToLocalDate (if this is the case your function should not be named as ConvertToLocalDate)
Do nor use ToLocalTime().rest will work fine

How to parse a timespan in order to add it to a datetime?

I've got a string in the following format: 05/06/2019|1330|60
The output I'm looking for is: 05/06/2019T14:30:00
I'm attempting to parse out the TimeSpan portion right now:
public static string getProcedureEndingDateTime (string input) {
//05/06/2019|1330|60
string myDate = input.Split ( '|' ) [0];
DateTime myDateTime = DateTime.Parse (myDate);
string myTime = input.Split('|')[1];
string hours = myTime.Substring(0,2);
string minutes = myTime.Substring(2,2);
TimeSpan myTimeSpan = TimeSpan.Parse($"{hours}:{minutes}");
myDateTime.Add(myTimeSpan);
return myDateTime.ToString();
}
But right now, getting the following output:
To get the above output I'm calling my function like so:
Console.WriteLine (getProcedureEndingDateTime("05/06/2019|1330|60"));
How do I parse the string "1330" into a TimeSpan?
No need to us a Timespan here, just call ParseExact instead with a proper format to do it in one line.
var myDateTime = DateTime.ParseExact("05/06/2019|1330|60", "dd/MM/yyyy|HHmm|60", CultureInfo.InvariantCulture);
Console.WriteLine(myDateTime.ToString());
//this gives 2019-06-05 1:30:00 PM, format depends on your PC's locale
I don't know what the 60 part is, you can adjust the format or substring it out beforehand.
The problem is because Add() returns a new DateTime instance, which means you're currently discarding it. Store it, and return that from your function instead, like so:
var adjusted = myDateTime.Add(myTimeSpan);
return adjusted.ToString();
Try using the numeric values as exactly that, numbers.
Also, the other issue with your code is the DateTime.Add() method doesn't add to that DateTime variable. Instead it returns a new variable, which you are ignoring.
Try this:
public static string getProcedureEndingDateTime (string input) {
string[] parts = input.Split('|');
string myDate = parts[0];
DateTime myDateTime = DateTime.Parse (myDate);
string myTime = parts[1];
if (!int.TryParse(myTime.Substring(0,2), out int hours))
hours = 0;
if (!int.TryParse(myTime.Substring(2,2), out int minutes))
minutes = 0;
TimeSpan myTimeSpan = new TimeSpan(hours, minutes, 0);
myDateTime += myTimeSpan;
return myDateTime.ToString();
}
Assuming the date shown is May 6th (and not June 5th), and also assuming the 60 represents a time zone offset expressed in minutes west of GMT, and also assuming you want the corresponding UTC value, then:
public static string getProcedureEndingDateTime (string input) {
// example input: "05/06/2019|1330|60"
// separate the offset from the rest of the string
string dateTimeString = input.Substring(0, 15);
string offsetString = input.Substring(16);
// parse the DateTime as given, and parse the offset separately, inverting the sign
DateTime dt = DateTime.ParseExact(dateTimeString, "MM/dd/yyyy|HHmm", CultureInfo.InvariantCulture);
TimeSpan offset = TimeSpan.FromMinutes(-int.Parse(offsetString));
// create a DateTimeOffset from these two components
DateTimeOffset dto = new DateTimeOffset(dt, offset);
// Convert to UTC and return a string in the desired format
DateTime utcDateTime = dto.UtcDateTime;
return utcDateTime.ToString("MM/dd/yyyy'T'HH:mm:ss", CultureInfo.InvariantCulture);
}
A few additional points:
Not only is the input format strange, but so is your desired output format. It is strange to see a T separating the date and time and also see the date in the 05/06/2019 format. T almost always means to use ISO 8601, which requires year-month-day ordering and hyphen separators. I'd suggest either dropping the T if you want a locale-specific format, or keep the T and use the standard format. Don't do both.
In ISO 8601, it's also a good idea to append a Z to UTC-based values. For DateTime values, the K specifier should be used for that. In other words, you probably want the last line above to be:
return utcDateTime.ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
// outputs: "2019-05-06T14:30:00Z"
You might want to not format a string here, but instead return the DateTime or DateTimeOffset value. It's usually better to create a string only at the time of display.
Don't forget that the DateTime struct is immutable. In your question you were ignoring the return value of the Add method.

Getting date in correct formatted for with proper timezone, among list of strings in an a array

I have a set of array.
//this is not hard corded, some times array will have multiple no.of strings in date format.
["vishnu","2016-08-31T18:30:00.000Z","1992","banglore"]
I have an array of strings, among these strings there is one string which is in date format.
I need to do a foreach and need to check which string is in the date format.
If we got the date string "2016-08-30T18:30:00.000Z" I need to convert it to basic date format but in correct timezone, here the date is 2016-08-31 but what I need as out put is
["vishnu","31/8/2016","1992","banglore"]
not
//check the difference in date!
["vishnu","30/8/2016","1992","banglore"]
the aim is from the array, if string is in date string format, convert it.
public static void Main(string[] args)
{
string inputString = "2016-08-31T18:30:00.000Z";
DateTime enteredDate = DateTime.Parse(inputString);
Console.WriteLine(enteredDate);
DateTime dDate;
if (DateTime.TryParse(inputString, out dDate))
{
DateTime dtx = enteredDate.ToLocalTime();
String.Format("{0:d/MM/yyyy}", dDate);
Console.WriteLine(dtx);
}
else
{
Console.WriteLine("Invalid"); // <-- Control flow goes here
}
// DateTime dt = convertedDate.ToLocalTime();
}
If you need to correct the DateTime for the time zone, you can use TimezoneInfo.ConvertTime():
string inputString = "2016-08-31T18:30:00.000Z";
DateTime dDate;
if (DateTime.TryParse(inputString, out dDate))
{
DateTime correctedDateTime = TimeZoneInfo.ConvertTime(dDate, TimeZoneInfo.Local);
// write this here back into the array using your format
Console.WriteLine(correctedDateTime.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture));
}
else
{
Console.WriteLine("Invalid"); // <-- Control flow goes here
}
For further reference check out this post. This answer is inspired by it to use TimeZoneInfo.
DateTime dDate;
do this operation iside foreach
if (DateTime.TryParse(answerString, out dDate))
{
DateTime enteredDate = DateTime.Parse(answerString);
var Date = enteredDate.ToString("dd/MM/yyyy");
answerString = Date;
Console.WriteLine(answerString);
}
else{
//operation
}
thanks to mong zhu
Try using DateTimeOffset rather than DateTime as it is built to handle time zones.
Here's the code:
string inputString = "2016-08-31T18:30:00.000Z";
DateTimeOffset enteredDate = DateTimeOffset.Parse(inputString);
Console.WriteLine(enteredDate);
DateTimeOffset dtx = enteredDate.ToLocalTime();
Console.WriteLine(dtx);
This produces the following for me in GMT+09:30:
2016/08/31 18:30:00 +00:00
2016/09/01 04:00:00 +09:30
To get it in Indian time try this:
DateTimeOffset dtx = enteredDate.ToOffset(TimeSpan.FromHours(5.5));
Console.WriteLine(dtx);
I get 2016/09/01 00:00:00 +05:30 now.

Get Date from DateTime without ToShortDateString

I am searching for this for about 2 hours and I don't have any ideas anymore.
The problem is I have a DateTime object and I need only the date part from it.
I tried
data.Date
create a new DateTime object like this
var x = new DateTime(data.Year,data.Months,data.Day)
I tried like this
DateTime.Parse(data.ToString("yyyy-MM-dd"))
NOTE: After getting the date part only, data needs to remain DateTime ( not string ), so I can not use ToShortDateString()
If you want some object, witch always return date in 2012-10-10 format from .ToString(), you can use this struct
struct Date
{
private DateTime dateTime;
public Date(DateTime dateTime)
{
this.dateTime = dateTime.Date;
}
public override string ToString()
{
return dateTime.ToString("yyyy-MM-dd");
}
}

What is the best way to get a formatted string to represent UTC offset? [duplicate]

This question already has answers here:
How to control appearance of ':' in time zone offset when parsing/formatting Datetime
(4 answers)
Closed 4 years ago.
I need to format a date like so: 20110202192008-0500. The following code does the trick but I was wondering if there is a better/cleaner way to do this in c# 3.5. Thanks!!
var date = DateTime.Now;
var strDate = TimeZoneInfo.ConvertTimeToUtc(date).ToString("yyyyMMddHHmmss");
var offsetHours = TimeZoneInfo.Local.GetUtcOffset(date).Hours.ToString("00");
var offsetMinutes = TimeZoneInfo.Local.GetUtcOffset(date).Minutes.ToString("00");
Console.Write(string.Concat(strDate, offsetHours, offsetMinutes));
How about this:
.NET 4
var utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
Console.WriteLine(DateTime.UtcNow.ToString("yyyyMMddHHmmss") + ((utcOffset < TimeSpan.Zero) ? "-" : "+") + utcOffset.ToString("hhmm"));
.NET 3.5
var utcAlmostFormat = DateTime.UtcNow.ToString("yyyyMMddHHmmss") + TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
var utcFormat = System.Text.RegularExpressions.Regex.Replace(utcAlmostFormat, #"(\d\d):(\d\d):(\d\d)",#"$1$2");
Console.WriteLine(utcFormat);
Go Steelers (from a guy in the Strip)
If you have a DateTimeOffset, the custom specifier zzz will output the timezone offset, though in the more standard "+HH:mm" format. If you don't want the colon, a string replace will do the trick.
Debug.WriteLine(DateTimeOffset.Now.ToString("yyyyMMddHHmmsszzz").Replace(":", ""));
// Result: "20110202153631-0500"
Here are some extension methods that will work in both .Net 3.5 and .Net 4.0 that will do exactly what you are asking in a very straight-forward way:
public static string ToStringWithOffset(this DateTime dt)
{
return new DateTimeOffset(dt).ToStringWithOffset();
}
public static string ToStringWithOffset(this DateTime dt, TimeSpan offset)
{
return new DateTimeOffset(dt, offset).ToStringWithOffset();
}
public static string ToStringWithOffset(this DateTimeOffset dt)
{
string sign = dt.Offset < TimeSpan.Zero ? "-" : "+";
int hours = Math.Abs(dt.Offset.Hours);
int minutes = Math.Abs(dt.Offset.Minutes);
return string.Format("{0:yyyyMMddHHmmss}{1}{2:00}{3:00}", dt, sign, hours, minutes);
}
You can now call these on any DateTime or DateTimeOffset you wish. For example:
string s = DateTime.Now.ToStringWithOffset();
or
string s = DateTimeTimeOffset.Now.ToStringWithOffset();
or
TimeSpan offset = TimeZoneInfo.Local.GetUtcOffset(someDate);
string s = someArbitraryTime.ToStringWithOffset(offset);
or any other number of ways you can think of.
We found that DateTimeOffset.ToString("o") is best for that. Example:
DateTime.UtcNow.UtcToDateTimeOffset(User.GetTimeZone()).ToString("o");
If you need to convert from DateTime, use helper method like:
/// <summary>Converts from a UTC DateTime to the user's local DateTime</summary>
/// <param name="utcDateTime">UTC DateTime</param>
/// <param name="timeZoneInfo">The time zone info.</param>
/// <returns>The DateTime in the user's time zone</returns>
public static DateTimeOffset UtcToDateTimeOffset(this DateTime utcDateTime, TimeZoneInfo timeZoneInfo = null)
{
if (utcDateTime.Kind != DateTimeKind.Utc)
{
throw new InvalidTimeZoneException("Converting UTC to Local TimeZone, but was not UTC.");
}
DateTimeOffset dto = new DateTimeOffset(utcDateTime, TimeSpan.Zero);
return timeZoneInfo.IsNotNull() ? dto.ToOffset(timeZoneInfo.GetUtcOffset(dto)) : dto;
}
You can use one of the DateTime Standard Formats or create a Custom Format.
// Round-trip date/time pattern: "O", "o"
DateTime.Now.ToString("o") // "2018-01-15T11:00:50.5604578-05:00"
DateTime.UtcNow.ToString("o") // "2018-01-15T16:00:50.5604578Z"
// Universal sortable date/time pattern: "u"
DateTime.Now.ToString("u") // "2018-01-15 16:00:50.5604578Z"
DateTime.UtcNow.ToString("u") // "2018-01-15 16:00:50.5604578Z"
// Custom format
DateTime.Now.ToString("yyyyMMddHHmmssK") // "20180115160050-05:00"
DateTime.UtcNow.ToString("yyyyMMddHHmmssK") // "20180115160050Z"
Try to use
var date = DateTimeOffset.Now;
var timestamp = $"{date:yyyy-MM-dd'T'HH:mm:ss.fff}{date.Offset.Ticks:+;-;}{date.Offset:hhmm}";
... or something like this.
I think there are a lot of ways, for example:
var offset = TimeZoneInfo.Local.BaseUtcOffset;
string result = DateTime.UtcNow.ToString("yyyyMMddHHmmss") + offset.Hours.ToString("00") + offset.Minutes.ToString("00");

Categories

Resources