简体   繁体   中英

Treating `NodaTime.LocalDate` as an unsigned value

I often find myself working with databases with nullable date fields so other return something along the lines of select coalesce( t.dt, cast( '0001-01-01' as date) ) from t (for sql server) and implicitly treating LocalDate as a unsigned value in my code. LocalDate defines a MinIsoValue and MaxIsoValue defining the smallest and biggest value that can be represented. MinIsoValue is defined as -9998-01-01 obviously stating LocalDate is a signed value. Usually negative dates don't really make sense in my problem domain hence that I refer to 0001-01-01 as "the beginning of time" in most cases.

My questions are:

  • Why is there no LocalDate.Zero ? If the min and max are demarcated I think it would make sense to define "the middle" or "zero" as the point from where the sign starts to matter.
  • I can't be the only one who has dealt with this but I can't really find any super useful information on how to deal with this. I've tried looking in the NodaTime newsgroup, tickets and SO questions. How do other people solve this? In the case of a database query just use '-9998-01-01' instead of '0001-01-01' ? Are there better solutions?
  • Most of the software I'm writing doesn't need negative dates, and in most of my cases it wouldn't make sense and would like an exception if it does happen. Does a unsigned version of LocalDate make sense?

(I'm using LocalDate as an example here, same applies to LocalDateTime . Not to sure about LocalTime as I never have to reason at that low of a resolution about time.)

LocalDate.Zero doesn't really have any particularly special meaning - it just happens to be where BCE becomes CE. You can easily create your own static property for it though. (I don't remember ever seeing a feature request for this.)

As Sweeper said, it's not that LocalDate is "signed" - the "absolute year zero" is pretty arbitrary, and the year 1 in one calendar will often be a different year in a different calendar. I strongly suspect that in the vast majority of problem domains where the year 1BCE isn't relevant, the year 1CE isn't relevant either... if you're only thinking about "modern dates" then you'll probably have a cut-off of 1800CE or later. If you're actually dealing with historical dates that go as far back as 1CE, then it's pretty likely you need to handle 1BCE too.

I suspect you're fine to just keep writing database queries that coalesce null to 0001-01-01, and if you want to make sure you don't have any dates earlier than that, you can just use value = LocalDate.Max(value, YourConstantClass.MinLocalDate) or similar to "clamp" it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM