I have a MVC3 application in which i want to set a timespan to for example 2 days and 5 hours.
when i enter 02:05:00:00 it gives me the following exception:
System.OverflowException: SqlDbType.Time overflow. Value '2.05:00:00' is out of range. Must be between 00:00:00.0000000 and 23:59:59.9999999.
When i enter 05:00:00 it correctly saves 5 hours into the database. according to MSDN timespan has a property for days. How do i correctly set the days?
Model:
public class ProductionTimeVM
{
[Required]
public TimeSpan DefaultTime { get; set; }
}
In my view i just use:
#Html.TextBoxFor(x => x.DefaultTime)
For my controller:
public ActionResult SaveProductionTime(ProductionTimeVM vm)
{
ProductionTime productionTime = new ProductionTime();
productionTime.Default = vm.DefaultTime;
//some more code
}
Any idea's?
You are probably saving a TimeSpan value to column with Time datatype in database. Time can only express a time of day, so you can't save TimeSpans larger than a day.
I use columns with bigint data type to store and retrieve ticks of TimeSpan. I would also like to know if there is a better alternative. This behavior is like default for some popular ORMs and it's misleading a lot of people I think.
Related
Im showing Warrenty_Expires of product in my view , but sometimes Warrenty_Expires contains value exactly like this 1753-01-01 00:00:00.000 and i want to say if Warrenty_Expires contains this value should not display it in my view.Can anyone please help me or point me into the right direction :)
This is i end up with but its not working and still showing this value (1753-01-01).
View:
if (Field.WarrentyExpiress.HasValue) //Check for null value
{
//Check if Warrenty contains this value(1753-01-01)
if (Field.WarrentyExpiress.Value.ToString().Contains("1753-01-01"))
{
<td>Not available</td>
}
else
{
<td>#Field.WarrentyExpiress.Value.ToString("MM/dd/yyyy")</td>
}
}
else
{
<td>Not available</td>
}
Model:
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime Warrenty_Expires { get; set; }
ViewModel:
public DateTime? WarrentyExpiress { get; set; }
Don't mess around with string representations of DateTime, simply compare against another instance of the DateTime struct:
if (Field.WarrentyExpiress.Value == new DateTime(1753, 1, 1).Date)
{
<td>Not available</td>
}
BTW, an interesting read: Why 1753?
What if you want to use multilingual? I would use the Date property of the DateTime.
if (Field.WarrentyExpiress.Value.Date == new DateTime(1753,1,1))
{
....
}
Never compare ToString() when something is regional dependend.
It's very unlikely that the year 1753 would be anything but this special case, so you could even do:
if (Field.WarrentyExpiress.Value.Year == 1753)
Do not try to do this via string processing. String is just about the 2nd worst format you could work with.
Figure out the actuall value of DateTime.Ticks that 1753-01-01 00:00:00.000 represents. DateTime just stores the amount of ticks since 1st January 0001 00:00:00.000. Every other value - the day, the month, the year, the string representation - are just a interpretation of that Tick value.
Once you know what the tick count is, you can check for anything less or equal to that count and filter it out.
This question already has answers here:
Milliseconds in my DateTime changes when stored in SQL Server
(4 answers)
Closed 7 years ago.
I save a datetime using C# Entity Framework, and when I load that time back from the database, the time varies from the value that I saved by 1 or more milliseconds.
Here is the C# Code:
public List<DateTime> TestDate()
{
var dates = new List<DateTime>();
DateTime testvalue = DateTime.Now;
dates.Add(testvalue);
IactexGMG2Entities firstContext = new IactexGMG2Entities();
var firstQuery = from p in firstContext.LocationProperties
where p.locationPropertyId == 4
select p;
var firstRec = firstQuery.Single();
firstRec.locationPropertyDateTime = testvalue;
firstContext.SaveChanges();
firstContext.Dispose();
IactexGMG2Entities secondContext = new IactexGMG2Entities();
var secondQuery = from p in secondContext.LocationProperties
where p.locationPropertyId == 4
select p;
var secondRec = secondQuery.Single();
var secondDate = secondRec.locationPropertyDateTime ?? DateTime.Now;
dates.Add(secondDate);
secondContext.Dispose();
return dates;
}
Here are the received values:
5/29/2015 5:43:25 PM . 154 , 635685182051540566
5/29/2015 5:43:25 PM . 153 , 635685182051530000
Here is the razor code that displays the values:
#foreach (var date in Model)
{
counter++;
<div>
#date . #date.Millisecond , #date.Ticks
</div>
}
As you can see, the second value, which was read back from the database, is lower than the first value by 1.0566 milliseconds.
The amount of variation varies, positive and negative, always with a small number of milliseconds.
Does anyone know how the conversion between the date values takes place?
Note: If I use the same context to read the date value, the values match. I assume that is because it is using the cached value, rather than the SQL Server value.
The problem is the different resolution between TSQL datetime and .NET DateTime data types
datetime only has a small resolution and is rounded to increments of .000, .003, or .007 seconds, whereas DateTime has a resultion of 100ns
Just use the new datetime2 SQL Data Type, which has the same resolution as .NET's DateTime, which is anyway recommended in new work, exactly for the issue you noticed
This actually has very little to nothing to do with Entity Framework. SQL Server as of 2008 has two DateTime types:
DateTime
Accuracy : Rounded to increments of .000, .003, or .007 seconds
DateTime2
Accuracy : 100 nanoseconds
Using Code-First Annotations you can set the property type like:
public MyClass
{
[Column(“CreatedOn", TypeName="DateTime2")]
public DateTime CreatedOn { get; set; }
}
Or using Fluent API:
modelBuilder.Entity<MyClass>()
.Property(p => p.CreatedOn)
.HasColumnType("DateTime2");
How can ı convert datetime to smalldatetime in c# ? I'm taking the date and ı need to convert it to be accordance with database. It is forbidden to change the datatype of column in sql.
You can use the .NET DateTime type for your entity framework model, but tell EF that it uses a non-default column type in the database. You do this by overriding the OnModelCreating method of your DbContext, and using the HasColumnType method:
public class Foo
{
public int Id { get; set; }
public DateTime IAmSoSmall { get; set; } // wants to be smalldatetime in SQL
}
public class MyContext : DbContext
{
public DbSet<Foo> Foos { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var foo = modelBuilder.Entity<Foo>();
foo.Property(f => f.IAmSoSmall).HasColumnType("smalldatetime");
base.OnModelCreating(modelBuilder);
}
}
Of course, you'll have to do the appropriate range-checking on your DateTime property to be sure that the stored values fall between those supported by SQL's smalldatetime. I guess you could do that with a property attribute like:
[Range(typeof(DateTime), "1/1/1900", "6/6/2079")]
public DateTime IAmSoSmall { get; set; } // wants to be smalldatetime in SQL
...based on a valid range from January 1, 1900, through June 6, 2079, as documented on MSDN.
Sql Server datetime and smalldatetime are both automatically mapped to and from the CLR's System.DateTime. A smalldatetime has a precision of 1 minute; a datetime has a precision of approximately 1/300 of a second (Don't ask why. It just is). Since the CLR's System.DateTime1 has a precision of 100-nanoseconds, the runtime takes care of rounding.
smalldatetime is internally a 32-bit integer, containing a count of minutes since the smalldatetime epoch (1900-01-01 00:00).
In conversion, seconds and fractional seconds are rounded using SQL Server's arcane date/time rounding rules, so the date 2013-01-31 23:59:59 gets rounded to the next date 2013-02-01 00:00:00'.
datetime is a pair of 32-bit integers internally. The high-order word is a count of days since the epoch; the low-order word is a count of milliseconds since start-of-day (00:00:00). The epoch of a datetime is 1900-01-01 00:00:00.000.
And again, values are rounded in the conversion in the same arcane way, with franctional seconds getting placed into one of the appropriate millisecond buckets for SQL Server, a multiple of 3ms — there is no SQL Server `datetime value like 2013-05-01 13:57:23.004. That will get "rounded" to either 23.003ms or 23.006ms.
If you want more control over things, you'll need to adjust your datetime values in C# before sending them to the database.
Maybe you can do something like YourDateTime.Date
Normally, when you do that way, it will set time to 00:00:00.
I'd like to know if exists any library / method that allows to sum days to a datetime without consider the "no work days" like Easter, Christmas, Saturdays and so on..
I know that exists the method DateTime.Add, but this didn't consider "non working days".
Thank you very much!
You can use the TimeSpan structure for time intervals. Here is an example on another stackoverflow thread:
Calculate the number of business days between two dates?
MSDN Documentation for TimeSpan
No, you'd have to define your own non-work days and build your own function.
There is a DateTime method that will tell you the day of the week, so you can check for Sat/Sun but the rest is up to you. If you are going to be using it with Office there are some dlls in there that could be used. Otherwise you will probably want to find a open-source project (lots of them out there) that can calculate that out for you.
DateTime.Now.DayOfWeek
It is going to be very region specific, so if you are planning on using your code in more than one country that is something to consider. Also, in the US, different states have different holidays too.
I'm assuming you want to find the end date for something given a start date and the number of working days that it will take?
If so, this the following code may be what you want. It assumes that you have a list of all the holidays for the maximum range of time that you are supporting. That could be a few years in the future, depending on your requirements!
This code takes the start date and the number of working days (and the list of holidays) and returns the end date.
public static DateTime AddWorkingDays(DateTime start, int workingDays, IEnumerable<DateTime> holidays)
{
var dict = new HashSet<DateTime>(holidays);
DateTime date;
for (date = start; workingDays > 0; date = date.AddDays(1))
{
if (!dict.Contains(date))
{
--workingDays;
}
}
return date;
}
An alternative implementation assumes that you have a predicate you can call to determine if a day is a holiday:
public static DateTime AddWorkingDays(DateTime start, int workingDays, Predicate<DateTime> isHoliday)
{
DateTime date;
for (date = start; workingDays > 0; date = date.AddDays(1))
{
if (!isHoliday(date))
{
--workingDays;
}
}
return date;
}
Both of these implementations suffer from visiting every date. This is possibly not an issue, but if the date range is large it could be too slow.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Based on date, get todays and the next two days values from XML?
I have asked some questions earlier, and thanks to excellent help from stackoverflow, i have solved a lot of the main issues. Thank you all!
I am extremely sorry if my questions are stupid, but i have tried to google as much as i can before asking here at stackoverflow.
I also have a working page where i can get specific prayer times and populate textblocks.
See this link and my marked question with the solution. There i use public timespan in the class and the var query:
How to make an if statement to show xml attribute based on current time
I am still working on the muslim PrayerTime app, and want to populate a listBox with todays+the next 3 days prayer times.
DateTime myDay = DateTime.Now;
XDocument loadedCustomData = XDocument.Load("WimPrayerTime.xml");
var filteredData = from c in loadedCustomData.Descendants("PrayerTime")
where c.Attribute("Day").Value == myDay.Day.ToString()
&& c.Attribute("Month").Value == myDay.Month.ToString()
select new PrayerTime()
{
Fajr = c.Attribute("Fajr").Value,
Soloppgang = c.Attribute("Soloppgang").Value,
Zohr = c.Attribute("Zohr").Value,
};
listBox1.ItemsSource = filteredData;
my Class is:
public class Prayertime
{
public string Fajr { get; set; }
public string Sunrise { get; set; }
public string Zohr { get; set; }
}
my local XML file (always included in the app it self)
<PrayerTime
Day ="30"
Month="4"
Fajr="07:00"
Sunrise="09:00"
Zuhr="14:00"
/>
<PrayerTime
Day ="1"
Month="5"
Fajr="07:05"
Sunrise="09:05"
Zuhr="14:05"
/>
<PrayerTime
Day ="2"
Month="5"
Fajr="07:10"
Sunrise="09:10"
Zuhr="14:10"
/>
First of all, how to change this code to show me a list of today plus the next three days?
where c.Attribute("Day").Value == myDay.Day.ToString()
Or should i make one query for each day,
DateTime NextDay = DateTime.Now.AddDays(1) and so on? How to i populate the same listBox with three or four different querys like this?
Can i just repeat this:
listBox1.ItemsSource = filteredData1;
listBox1.ItemsSource = filteredData2;
listBox1.ItemsSource = filteredData3;
Also, what to do when the month changes? For example, if the date is 30 and month is 4 next day will be value 1 and month should then show 5?
Last but not least.. when showing the information i want the listBox to show it like:
Monday 30.04.2012
Fajr 07:00
Sunrise 09:00
Zuhr 14:00
Tuesday 01.05.2012
Fajr 07:05
Sunrise 09:10
Zuhr 14:10
where i have a fixed spacing between the Attribute name and value, and the date/day above.
Thank you very much to everyone who takes the time to read, and huge thanks to everyone who answers:)
Try this:
where int.Parse(c.Attribute("Day").Value) >= myDay.Day && int.Parse(c.Attribute("Day").Value) < (myDay.Day + 3)