Insert time without the date into my database - c#

I tried to insert into my MS Access database a specific format to see how just the "time" in my database behaves, but when I tried to show what I got the date also, but I want to insert just the time.
I tried to convert the datetime variable to specific format and insert that
DateTime starttime = Convert.ToDateTime(DateTime.Now.ToShortTimeString());
DateTime nstarttime = Convert.ToDateTime(starttime.ToString("HH:mm"));
06/04/2019 22:55:00 that what I got and I want just the time
without the date

Your main issue is, that in .Net the time part of a DateTime is not a DateTime but a TimeSpan:
DateTime dateTime = new DateTime(2019, 6, 4, 22, 55, 0);
TimeSpan timePart = dateTime.TimeOfDay;
In Access (VBA) however, a "time only" value is the time of the date of the VBA Date epoch which is 1899-12-30. Depending on how you insert the time in an Access table, you may have to apply the time part to the epoch to obtain a value like that Access would use:
DateTime dateTime = new DateTime(2019, 6, 4, 22, 55, 0);
TimeSpan timePart = dateTime.TimeOfDay;
DateTime vbaEpoch = new DateTime(1899, 12, 30);
DateTime vbaTime = vbaEpoch.AddTicks(timePart.Ticks);
Of course, when reading back the values, ignore the date part:
TimeSpan timeOfDay = vbaTime.TimeOfDay;

This has been answered so many times, but nevertheless here is the link to one of the discussions Link 1:
Please check also this Link 2 with may useful patterns
This detail is one of the actual examples provided on Link 1:
DateTime dt = DateTime.Parse("6/22/2009 07:00:00 AM");
dt.ToString("HH:mm"); // 07:00 // 24 hour clock // hour is always 2 digits
dt.ToString("hh:mm tt"); // 07:00 AM // 12 hour clock // hour is always 2 digits
dt.ToString("H:mm"); // 7:00 // 24 hour clock
dt.ToString("h:mm tt"); // 7:00 AM // 12 hour clock
Hope this helps!
Cheers and happy coding!

Related

Setting datetime to a specific date by specific way

I have a variable with date time which I have to set on a specific date by these rukles and scenarios:
The API that I connect to has a daily limit and once that limit is reached I have to wait until NEXT DAY until 9:10 AM CEST <= This is very important
So I've been simply doing this:
var localTime = TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time"));
var tomorrowAt0910 = localTime.AddDays(1).Date + new TimeSpan(9, 10, 0);
And I have realized that this code has a bug, because I can have following scenarios:
Let's say my application would expire on 30th of July at 15:00 PM in which case this logic up there would be VALID
BUT
We have a next following scenario which is more likely to happen:
Application expires on 31st of July 5:00 AM, in which case this logic is faulty because RENEWAL DATE will be set to 1st of August 9:10AM WHICH IS BAD
If the application expires in this second case, I should set the date to same day and few hours difference (from 5AM to 9AM)
How could I do this?
It sounds like what you really want is to say:
Find the current time in Central Europe
Find 9:10am on the same date
If 9:10am is after the current time, add a day
So something like:
// No need to do this more than once
private static readonly TimeZoneInfo centralEuropeZone =
TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time")
private static DateTime GetUtcResetTime()
{
// Using UtcNow to make it clear that the system time zone is irrelevant
var centralEuropeNow = TimeZoneInfo.ConvertTime(DateTime.UtcNow, centralEuropeZone);
var centralEuropeResetTime = centralEuropeNow.Date + new TimeSpan(9, 10, 0);
if (centralEuropeResetTime <= centralEuropeNow)
{
centralEuropeResetTime = centralEuropeResetTime.AddDays(1);
}
return TimeZoneInfo.ConvertTimeToUtc(centralEuropeResetTime, centralEuropeZone);
}
I've made that return a UTC DateTime so that no other code needs to worry about which zone it's in.
Check if the expire date is less that the current date, if so add one day.
DateTime expireDate = new DateTime(2018, 7, 30, 22, 0, 0); //for testing
DateTime tomorrowAt0910 = DateTime.Now.Date.AddHours(9).AddMinutes(10);
if (expireDate.Date < DateTime.Now.Date)
{
tomorrowAt0910.AddDays(1);
}

Why doesn't subtracting two local DateTime values appear to account for Daylight Saving Time?

I'm playing with some C# code to try to gain an understanding of how subtracting DateTime objects in C# works with respect to Daylight Saving Time.
Per Google and other sources, the Daylight Saving Time "spring ahead" event in the Eastern Standard Time zone in 2017 was at 2:00am on March 12. So, the first few hours of the day on that date were:
12:00am - 1:00am
1:00am - 2:00am
(There was no 2:00am - 3:00am hour due to the "spring ahead")
3:00am - 4:00am
So, if I were to calculate the time differential between 1:00am and 4:00am in that time zone on that date, I'd expect the result to be 2 hours.
However, the code I put together to try to simulate this problem is returning a 3 hour TimeSpan.
Code:
TimeZoneInfo easternStandardTime = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime oneAm = TimeZoneInfo.ConvertTime(new DateTime(2017, 03, 12, 01, 00, 00), easternStandardTime);
DateTime fourAm = TimeZoneInfo.ConvertTime(new DateTime(2017, 03, 12, 04, 00, 00), easternStandardTime);
TimeSpan difference = (fourAm - oneAm);
Console.WriteLine(oneAm);
Console.WriteLine(fourAm);
Console.WriteLine(TimeZoneInfo.Local.IsDaylightSavingTime(oneAm));
Console.WriteLine(TimeZoneInfo.Local.IsDaylightSavingTime(fourAm));
Console.WriteLine(difference);
On my PC, this generates:
2017-03-12 01:00:00.000 -5
2017-03-12 04:00:00.000 -4
False
True
03:00:00
All of that output is as expected -- except that final value of 3 hours, which as I noted above, I would expect to be 2 hours instead.
Obviously, my code isn't correctly simulating the situation that I have in mind. What is the flaw?
Observe:
// These are just plain unspecified DateTimes
DateTime dtOneAm = new DateTime(2017, 03, 12, 01, 00, 00);
DateTime dtFourAm = new DateTime(2017, 03, 12, 04, 00, 00);
// The difference is not going to do anything other than 4-1=3
TimeSpan difference1 = dtFourAm - dtOneAm;
// ... but we have a time zone to consider!
TimeZoneInfo eastern = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
// Use that time zone to get DateTimeOffset values.
// The GetUtcOffset method has what we need.
DateTimeOffset dtoOneAmEastern = new DateTimeOffset(dtOneAm, eastern.GetUtcOffset(dtOneAm));
DateTimeOffset dtoFourAmEastern = new DateTimeOffset(dtFourAm, eastern.GetUtcOffset(dtFourAm));
// Subtracting these will take the offset into account!
// It essentially does this: [4-(-4)]-[1-(-5)] = 8-6 = 2
TimeSpan difference2 = dtoFourAmEastern - dtoOneAmEastern;
// Let's see the results
Console.WriteLine("dtOneAm: {0:o} (Kind: {1})", dtOneAm, dtOneAm.Kind);
Console.WriteLine("dtFourAm: {0:o} (Kind: {1})", dtFourAm, dtOneAm.Kind);
Console.WriteLine("difference1: {0}", difference1);
Console.WriteLine("dtoOneAmEastern: {0:o})", dtoOneAmEastern);
Console.WriteLine("dtoFourAmEastern: {0:o})", dtoFourAmEastern);
Console.WriteLine("difference2: {0}", difference2);
Results:
dtOneAm: 2017-03-12T01:00:00.0000000 (Kind: Unspecified)
dtFourAm: 2017-03-12T04:00:00.0000000 (Kind: Unspecified)
difference1: 03:00:00
dtoOneAmEastern: 2017-03-12T01:00:00.0000000-05:00)
dtoFourAmEastern: 2017-03-12T04:00:00.0000000-04:00)
difference2: 02:00:00
Note that DateTime carries a DateTimeKind in its Kind property, which is Unspecified by default. It doesn't belong to any particular time zone. DateTimeOffset doesn't have a kind, it has an Offset, which tells you how far that local time is offset from UTC. Neither of these give you the time zone. That is what TimeZoneInfo object is doing. See "time zone != offset" in the timezone tag wiki.
The part I think you are perhaps frustrated with, is that for several historical reasons, the DateTime object does not ever understand time zones when doing math, even when you might have DateTimeKind.Local. It could have been implemented to observe the transitions of the local time zone, but it was not done that way.
You also might be interested in Noda Time, which gives a very different API for date and time in .NET, in a much more sensible and purposeful way.
using NodaTime;
...
// Start with just the local values.
// They are local to *somewhere*, who knows where? We didn't say.
LocalDateTime ldtOneAm = new LocalDateTime(2017, 3, 12, 1, 0, 0);
LocalDateTime ldtFourAm = new LocalDateTime(2017, 3, 12, 4, 0, 0);
// The following won't compile, because LocalDateTime does not reference
// a linear time scale!
// Duration difference = ldtFourAm - ldtOneAm;
// We can get the 3 hour period, but what does that really tell us?
Period period = Period.Between(ldtOneAm, ldtFourAm, PeriodUnits.Hours);
// But now lets introduce a time zone
DateTimeZone eastern = DateTimeZoneProviders.Tzdb["America/New_York"];
// And apply the zone to our local values.
// We'll choose to be lenient about DST gaps & overlaps.
ZonedDateTime zdtOneAmEastern = ldtOneAm.InZoneLeniently(eastern);
ZonedDateTime zdtFourAmEastern = ldtFourAm.InZoneLeniently(eastern);
// Now we can get the difference as an exact elapsed amount of time
Duration difference = zdtFourAmEastern - zdtOneAmEastern;
// Dump the output
Console.WriteLine("ldtOneAm: {0}", ldtOneAm);
Console.WriteLine("ldtFourAm: {0}", ldtFourAm);
Console.WriteLine("period: {0}", period);
Console.WriteLine("zdtOneAmEastern: {0}", zdtOneAmEastern);
Console.WriteLine("zdtFourAmEastern: {0}", zdtFourAmEastern);
Console.WriteLine("difference: {0}", difference);
ldtOneAm: 3/12/2017 1:00:00 AM
ldtFourAm: 3/12/2017 4:00:00 AM
period: PT3H
zdtOneAmEastern: 2017-03-12T01:00:00 America/New_York (-05)
zdtFourAmEastern: 2017-03-12T04:00:00 America/New_York (-04)
difference: 0:02:00:00
We can see a period of three hours, but it doesn't really mean the same as the elapsed time. It just means the two local values are three hours apart in their position on a clock. NodaTime understands the difference between these concepts, while .Net's built-in types do not.
Some follow-up reading for you:
What's wrong with DateTime anyway?
More Fun with DateTime
The case against DateTime.Now
Five Common Daylight Saving Time Antipatterns of .NET Developers
Oh, and one other thing. Your code has this...
DateTime oneAm = TimeZoneInfo.ConvertTime(new DateTime(2017, 03, 12, 01, 00, 00), easternStandardTime);
Since the DateTime you create has unspecified kind, you are asking to convert from your computer's local time zone to Eastern time. If you happen to be not in Eastern time, your oneAm variable might not be 1 AM at all!
Ok, so I made some minor changes to your code. Not sure if this is what you are trying to achieve or not but this will give you what you want...
static void Main() {
TimeZoneInfo easternStandardTime = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
TimeZone timeZone = TimeZone.CurrentTimeZone;
DateTime oneAm = TimeZoneInfo.ConvertTime(new DateTime(2017, 03, 12, 01, 00, 00), easternStandardTime);
DateTime fourAm = TimeZoneInfo.ConvertTime(new DateTime(2017, 03, 12, 04, 00, 00), easternStandardTime);
DaylightTime time = timeZone.GetDaylightChanges(fourAm.Year);
TimeSpan difference = ((fourAm - time.Delta) - oneAm);
Console.WriteLine(oneAm);
Console.WriteLine(fourAm);
Console.WriteLine(TimeZoneInfo.Local.IsDaylightSavingTime(oneAm));
Console.WriteLine(TimeZoneInfo.Local.IsDaylightSavingTime(fourAm));
Console.WriteLine(difference);
Console.ReadLine();
}
So this is addressed in the MSDN documentation.
Basicaly, when subtracting one date from another you should be using DateTimeOffset.Subtract() and not arithmetic subtraction as you have here.
TimeSpan difference = fourAm.Subtract(oneAm);
Yields the expected 2 hour time difference.

Are adding weeks, months or years to a date/time independent from time zone?

My software displays date/time using local time and then send it to server in UTC. On the server-side I want to add months, years, weeks, days etc to this date/time. However, the question is, if I use such methods with UTC date/time and then convert it back to local time, would the result be always the same, as if I use this methods with local time directly?
This is an example in C#:
// #1
var utc = DateTime.Now.ToUtcTime();
utc = utc.AddWeeks(2); // or AddDays, AddYears, AddMonths...
var localtime = utc.ToLocalTime();
// #2
var localtime = DateTime.Now;
localtime = localtime.AddWeeks(2); // or AddDays, AddYears, AddMonths...
Would the results in #1 and #2 always be the same? Or timezone can influence the result?
The answer may surprise you but it is NO. You cannot add days, weeks, months, or years to a UTC timestamp, convert it to a local time zone, and expect to have the same result as if you had added directly to the local time.
The reason is that not all local days have 24 hours. Depending on the time zone, the rules for that zone, and whether DST is transitioning in the period in question, some "days" may have 23, 23.5, 24, 24.5 or 25 hours. (If you are trying to be precise, then instead use the term "standard days" to indicate you mean exactly 24 hours.)
As an example, first set your computer to one of the USA time zones that changes for DST, such as Pacific Time or Eastern Time. Then run these examples:
This one covers the 2013 "spring-forward" transition:
DateTime local1 = new DateTime(2013, 3, 10, 0, 0, 0, DateTimeKind.Local);
DateTime local2 = local1.AddDays(1);
DateTime utc1 = local1.ToUniversalTime();
DateTime utc2 = utc1.AddDays(1);
DateTime local3 = utc2.ToLocalTime();
Debug.WriteLine(local2); // 3/11/2013 12:00:00 AM
Debug.WriteLine(local3); // 3/11/2013 1:00:00 AM
And this one covers the 2013 "fall-back" transition:
DateTime local1 = new DateTime(2013, 11, 3, 0, 0, 0, DateTimeKind.Local);
DateTime local2 = local1.AddDays(1);
DateTime utc1 = local1.ToUniversalTime();
DateTime utc2 = utc1.AddDays(1);
DateTime local3 = utc2.ToLocalTime();
Debug.WriteLine(local2); // 11/4/2013 12:00:00 AM
Debug.WriteLine(local3); // 11/3/2013 11:00:00 PM
As you can see in both examples - the result was an hour off, one direction or the other.
A couple of other points:
There is no AddWeeks method. Multiply by 7 and add days instead.
There is no ToUtcTime method. I think you were looking for ToUniversalTime.
Don't call DateTime.Now.ToUniversalTime(). That is redundant since inside .Now it has to take the UTC time and convert to local time anyway. Instead, use DateTime.UtcNow.
If this code is running on a server, you shouldn't be calling .Now or .ToLocalTime or ever working with DateTime that has a Local kind. If you do, then you are introducing the time zone of the server - not of the user. If your users are not in the same time zone, or if you ever deploy your application somewhere else, you will have problems.
If you want to avoid these kind of problems, then look into NodaTime. It's API will prevent you from making common mistakes.
Here's what you should be doing instead:
// on the client
DateTime local = new DateTime(2013, 3, 10, 0, 0, 0, DateTimeKind.Local);
DateTime utc = local.ToUniversalTime();
string zoneId = TimeZoneInfo.Local.Id;
// send both utc time and zone to the server
// ...
// on the server
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(zoneId);
DateTime theirTime = TimeZoneInfo.ConvertTimeFromUtc(utc, tzi);
DateTime newDate = theirTime.AddDays(1);
Debug.WriteLine(newDate); // 3/11/2013 12:00:00 AM
And just for good measure, here is how it would look if you used Noda Time instead:
// on the client
LocalDateTime local = new LocalDateTime(2013, 3, 10, 0, 0, 0);
DateTimeZone zone = DateTimeZoneProviders.Tzdb.GetSystemDefault();
ZonedDateTime zdt = local.InZoneStrictly(zone);
// send zdt to server
// ...
// on the server
LocalDateTime newDate = zdt.LocalDateTime.PlusDays(1);
Debug.WriteLine(newDate); // 3/11/2013 12:00:00 AM

Subtract time from date using format string

If I have a date and time in a DateTime object, can I remove say 10 minutes, or 24 hours etc from the date and time using a format string?
So if I have 1/1/1990 12:30:00pm and I wanted to remove 1 hour from it, can I use a format string?
edit
i need to store diary entries and the user can select a reminder type. so 1 hour before hand. so then i'd like to store the format string in a db that i can get and apply to a datetime to get the reminder date time
Something like this might do what you need. Not sure what you mean by subtracting an hour using a format string though.
DateTime dt = new DateTime(1990, 1, 1, 12, 30, 0);
string s = dt.Subtract(new TimeSpan(1, 0, 0)).ToString("MM/dd/yyyy hh:mm:ss tt")
Best way is to convert to a DateTime object and then back to the formatted string (if that's what you need):
var time = DateTime.Parse("1/1/1990 12:30:00pm");
time = time.AddMinutes(-10);
string timeString = time.ToString("MM/dd/yyyy hh:mm:ss tt");
You can use this in your query if you have..
DATE_SUB(date,INTERVAL expr unit)
Example:
YourDate = DATE_SUB(1/1/1990 12:30:00pm, INTERVAL 1 HOUR)
YourDate = DATE_SUB(1/1/1990 12:30:00pm, INTERVAL 12 MINUTE)
YourDate = DATE_SUB(1/1/1990 12:30:00pm, INTERVAL 45 SECONDS)

How to set only time part of a DateTime variable in C# [duplicate]

This question already has answers here:
How to change time in DateTime?
(29 answers)
Closed 9 years ago.
I have a DateTime variable:
DateTime date = DateTime.Now;
I want to change the time part of a DateTime variable. But when I tried to access time part (hh:mm:ss) these fields are readonly.
Can't I set these properties?
Use the constructor that allows you to specify the year, month, day, hours, minutes, and seconds:
var dateNow = DateTime.Now;
var date = new DateTime(dateNow.Year, dateNow.Month, dateNow.Day, 4, 5, 6);
you can't change the DateTime object, it's immutable. However, you can set it to a new value, for example:
var newDate = oldDate.Date + new TimeSpan(11, 30, 55);
date = new DateTime(date.year, date.month, date.day, HH, MM, SS);
I'm not sure exactly what you're trying to do but
you can set the date/time to exactly what you want in a number of ways...
You can specify 12/25/2010 4:58 PM by using
DateTime myDate = Convert.ToDateTime("2010-12-25 16:58:00");
OR if you have an existing datetime construct , say 12/25/2010 (and any random time) and you want to set it to 12/25/2010 4:58 PM, you could do so like this:
DateTime myDate = ExistingTime.Date.AddHours(16).AddMinutes(58);
The ExistingTime.Date will be 12/25 at midnight, and you just add hours and minutes to get it to the time you want.
It isn't possible as DateTime is immutable. The same discussion is available here: How to change time in datetime?

Categories