Simpler way to represent 1900 epoch in C# [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Is there a simpler way to calculate this? Perhaps via a method built-in to .NET?
var time = DateTime.Now.AddSeconds(8);
var year = 10000000000000 * (ulong)(time.Year - 1900);
var month = 100000000000 * (ulong)(time.Month - 1);
var dayofyear = 100000000 * (ulong)(time.DayOfYear - 1);
var day = (ulong)(time.Day * 1000000);
var Hour = (ulong)(time.Hour * 10000);
var Minute = (ulong)(time.Minute * 100);
var Second = (ulong)(time.Second);
var utcTime = year + month + dayofyear + day + Hour + Minute + Second;
Could it be DateTime.Now.AddSeconds(8).AllMilliseconds?
I've tried these methods
var test = (time - DateTime.MinValue).Milliseconds;
var tes2t = (time - DateTime.MinValue).TotalMilliseconds;

DateTime.MinValue is not 1900. The documentation for DateTime.MinValue says:
The value of this constant is equivalent to 00:00:00.0000000 UTC, January 1, 0001, in the Gregorian calendar.
Which is about 1899 years before the date you want. You want to do this:
double milliseconds = ( time - new DateTime( 1900, 1, 1 ) ).TotalMilliseconds
EDIT: As Rick suggests in the comments, the following might be better suited to your needs:
var epoch = new DateTime( 1900, 1, 1, 0, 0, 0, DateTimeKind.Utc );
double milliseconds = ( time - epoch ).TotalMilliseconds;

Related

How to divide period to weeks start from Saturday and end with Friday? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 months ago.
Improve this question
I have a period suppose its Start from 01/12/2022 and end in 30/12/2022 I want to divide this period to weeks the week must start from Saturday and end in Friday so expected result should be :
How I can do this using SQL server query
After a little bit of trial and error you need this:
DateTime StartOfWeek(DateTime when) =>
when.AddDays(-((8 + (int)when.DayOfWeek) % 7));
Here's a table of output:
var table =
Enumerable
.Range(0, 31)
.Select(x => new DateTime(2022, 12, 1).AddDays(x))
.GroupBy(x => StartOfWeek(x))
.Select(x => new
{
from = x.Min(),
to = x.Max(),
start = x.Key
});
A similar solution to Enigmativity's, for those who are not yet familiar with queries.
In general, you can find out the first day of the week like this:
(and choose which day the week should start)
DateTime curDate = new DateTime(2022, 12, 1);
DateTime result = FirstDateOfWeek(curDate, DayOfWeek.Saturday);
DateTime FirstDateOfWeek(DateTime day, DayOfWeek firstDayOfWeek=DayOfWeek.Monday)
{
int minus = day.DayOfWeek - firstDayOfWeek;
if (minus == 0)
return day.Date;
if (minus < 0)
minus = 7 + minus;
return day.Date - TimeSpan.FromDays(minus);
}
Just add 7 to the result for the next week.

Adding time as int [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Hello I am quite new to C# and I am facing difficulty in adding time as an int . For example,
01:30 Hr
09:45 Hr
13:27 Hr
are hours. I want to convert these to minutes.
How do I add these as int so that I get:
90 + 585 + 825
Is there a way to perform this operation in C#?
public int total_time;
void Start()
{
total_time = time_1 + time_2 + time_3;
}
Let's suppose that your time data are stored in this way:
var dataSource = new List<string>
{
"01:30 Hr",
"09:45 Hr",
"13:27 Hr"
};
Then all you need to do is to
get ride of the Hr suffix
convert them to TimeSpan
sum their TotalMinutes
var total = dataSource
.Select(data => data.Substring(0, 5))
.Select(time => TimeSpan.Parse(time).TotalMinutes)
.Sum();
Obviously this is a naive implementation and really fragile.
A more robust solution would use
regex to get the time portion of the string
use TimeSpan's TryParse to avoid runtime exceptions in case of mailformed inputs.
UPDATE
Based on the comment of Drag and Drop, here is an alternative which could give you better precision:
var total = dataSource
.Select(data => data.Substring(0, 5))
.Select(time => TimeSpan.Parse(time))
.Aggregate(TimeSpan.Zero, (t1, t2) => t1 + t2)
.TotalMinutes;
This approach could be used as well whenever you introduce seconds as well.
(You just need to adjust the Substring parameters.)
Why don't you use TimeSpan struct? TimeSpan struct does exactly what you want.
TimeSpan thirtyMinute = new TimeSpan(0, 30, 0); // Hours, Minutes, Seconds
TimeSpan s = new TimeSpan(1, 24, 60, 60, 100); // Day, Hours, Minutes, Seconds, Miliseconds
TimeSpan oneHour = thirtyMinute + thirtyMinute; // You can add TimeSpan to another == 1 Hour
Here is how to convert hour string
Debug.Log(string.Format("You were out of game for: {0} minutes and {1:00} seconds", (int)totalExitTime / 60, (int)totalExitTime % 60));

How to convert an integer to date? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I created a count down timer like this:
I set manuel values for startTime
var options = {
stepTime: 60,
format: "dd:hh:mm:ss",
startTime: "01:12:32:55",
digitImages: 6,
digitWidth: 53,
digitHeight: 77,
image: "digits.png"
};
I have lblDay,lblHours,lblMinutes,LblSeconds on page.
I can get TotalHours column from SQL.How can I convert value of TotalHours to like this :
lbDays:27
lblHours:2
lblMinutes:34
lblSeconds:08
int TotalHours = Convert.ToInt32(dt.Rows[0][11]);
//int TotalHours =664
and How can I set value of labels to startTime
int totalHours = 664; // example from question
TimeSpan ts = TimeSpan.FromHours(totalHours); // or similar
int days = (int)ts.TotalDays,
hours = ts.Hours,
// note the next will always be zero
// since we init in an integer
// number of hours
minutes = ts.Minutes,
seconds = ts.Seconds;

Parse DateTime in format: 15:31:58:13943730921 [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How do I parse the following time in C# ?
15:31:58:13943730921
What are the last 11 digits?
Something naive would be:
var time = "15:31:58:13943730921";
var str = time.Split(':');
var res = new TimeSpan(int.Parse(str[0]), int.Parse(str[1]), int.Parse(str[2])).Add(TimeSpan.FromTicks((long.Parse(str[3]) + 5000) / 10000));
Note that it won't work if the number of digits of the fractions of seconds change.
Ah... and it's a TimeSpan, not a DateTime probably :-)
The + 5000) / 10000 is to round to the nearest Tick.
A more complete solution that will handle any number of digits:
var time = "15:31:58:13943730921";
var str = time.Split(':');
// Used for the rounding
int carryover = 0;
if (str[3].Length < 7)
{
str[3] = str[3] + new string('0', 7 - str[3].Length);
}
else if (str[3].Length > 7)
{
char eight = str[3][7];
if (eight >= 5)
{
carryover = 1;
}
str[3] = str[3].Remove(7);
}
var res = new TimeSpan(int.Parse(str[0]), int.Parse(str[1]), int.Parse(str[2])).Add(TimeSpan.FromTicks(long.Parse(str[3]) + carryover));
Note that the TimeSpan constructor doesn't support a hour/minute/seconds + ticks, so we have to handle it in a different way (by using the .Add). Other solutions are clearly possible.
This is what I have done.
internal string GetTime(string line)
{
// ...
string tmp = time.Substring(0, 12);
time = DateTime.ParseExact(tmp, "HH:mm:ss:fff", CultureInfo.CurrentUICulture).Ticks.ToString();
return time;
}
If you want to round correctly to a whole number and ticks, with .NET 4.0 and later you can do:
string time = "15:31:58:13943730921";
var ts = TimeSpan.ParseExact(time.Remove(16), "h':'mm':'ss':'fffffff", null);
if (time[16] >= '5')
ts += new TimeSpan(1L); // add one tick for better rounding
Console.WriteLine(ts);
16 is the index in the string of the first character that we have to throw away.
May seem like an obvious answer.. But the question isn't too clear.
DataTime time = DateTime.Now;
string myTime = time.ToShortTimeString();
myTime = myTime.SubString(0, 7);

Subtracting TimeSpan from date

I want to subtract a time-span from a date-time object using a 30-day month and ignoring leap years etc.
Date is 1983/5/1 13:0:0 (y/m/d-h:m:s)
Time span is 2/4/28-2:51:0 (y/m/d-h:m:s)
I can use DateTime and TimeSpan objects to do this, after converting years and months of the time-span to days (assuming a 30 day month and a ~364 day year).
new DateTime(1981,5,1,13,0,0).Subtract(new TimeSpan(878,13,51,0));
With this i get the result:
{12/4/1978 11:09:00 PM}
Above answer obviously doesn't ignore the factors i want ignored and gives me an accurate answer. But in this case that's not what i want so i wrote the below code.
public static CustomDateTime operator -(CustomDateTime DT1,CustomDateTime DT2)
{
CustomDateTime retVal = new CustomDateTime();
try
{
const int daysPerYear = 364.25;
const int monthsPerYear = 12;
const int daysPerMonth = 30;
const int hoursPerDay = 24;
const int minutesPerHour = 60;
retVal.Minute = DT1.Minute - DT2.Minute;
if (retVal.Minute < 0)
{
retVal.Minute += minutesPerHour;
DT1.Hour -= 1;
}
retVal.Hour = DT1.Hour - DT2.Hour;
if (retVal.Hour < 0)
{
retVal.Hour += hoursPerDay;
DT1.Day -= 1;
}
retVal.Day = DT1.Day - DT2.Day;
if (retVal.Day < 0)
{
retVal.Day += daysPerMonth;
DT1.Month -= 1;
}
retVal.Month = DT1.Month - DT2.Month;
if (retVal.Month < 0)
{
retVal.Month += monthsPerYear;
DT1.Year -= 1;
}
retVal.Year = DT1.Year - DT2.Year;
}
catch (Exception ex) { }
return retVal;
}
Then i get:
1981/0/3-10:9:0
This is pretty close to what i'm after except i shouldn't get 0 for month and year should be 1980. Any kind of help is appreciated.
Just to make things clear again; in this context I have to use a 30-day month and ignore leap-years, different numbers of months, etc. Its a weird thing to do, i know. So I'm pretty much after a 'wrong answer' as opposed to the exact answer given by the managed classes.
If you're estimating a month at 30 days, of course your math will be off. When you subtract 878 days from 5/1/1981, .Net is giving you the exact difference, not an estimate, and this difference accounts for leap years, if there are any. The error is not in the Subtract(...) method - it is in your own "manual" calculation.
DateTime dt = new DateTime(1981, 5, 1, 13, 0, 0);
TimeSpan t = new TimeSpan(878, 13, 51, 0);
dt.Ticks
624931668000000000
t.Ticks
759090600000000
dt.Ticks - t.Ticks
624172577400000000
new DateTime(dt2)
{12/4/1978 11:09:00 PM}
Date: {12/4/1978 12:00:00 AM}
Day: 4
DayOfWeek: Monday
DayOfYear: 338
Hour: 23
Kind: Unspecified
Millisecond: 0
Minute: 9
Month: 12
Second: 0
Ticks: 624172577400000000
TimeOfDay: {23:09:00}
Year: 1978
These are the total ticks since the epoch. Do this math, then convert back into a datetime.
Also: correct your math. 878 days is 2 years and 148 days. 5/1/1981 is the 121st day of the year, so subtract 120 to get Jan 1, 1979. This leaves 28 days. Start counting backwards from the end of 1978, and you get very close to the .Net answer. Your own answer isn't anywhere close.
EDIT based on feedback
// zh-Hans is a chinese culture
CultureInfo ci = CultureInfo.GetCultureInfo("zh-Hans");
DateTime dt = new DateTime(1981, 5, 1, 13, 0, 0, ci.Calendar);
TimeSpan t = new TimeSpan(878, 13, 51, 0);
Please note that you are still subtracting 878 days. The length of a month would be irrelevant in that case based on the Julian calendar. You will probably need to find the correct culture code for your particular calendar, then try this. However, with this calendar, I still arrive at the same answer above.
Beyond doing this, I am unsure how else to do the math. If you can provide a link to how you are doing it by hand, I can help code it for you.
EDIT 2
I understand now. Try this:
DateTime dt = new DateTime(1981, 5, 1, 13, 0, 0, ci.Calendar);
int years = 878 / 365;
int remainingDays = 878 % 365;
int months = remainingDays / 30;
remainingDays = remainingDays % 30;
TimeSpan t = new TimeSpan(years * 365 + months * 30 + remainingDays);
DateTime newdate = dt.Subtract(t);
You cannot assume a 30-day month. You are specifying that you want to subtract 878 days. The managed classes (I'm assuming you mean managed when you say native) are designed to factor in leap-years, different numbers of months, etc.
Using the managed classes will not give you a 0 for a month.

Categories