0

I have used NodaTime with c# a lot, and it has been fantastic, but was caught out when trying to obtain the total minutes between two LocalDateTimes. My two times are more than a week apart.

This does not deliver a valid result: (1)

long Mns = Period.Between(nowLdt,triggerLdt).Ticks.ToSeconds() / 60; 

This does deliver the correct result: (2)

double Mns = Period.Between(nowLdt,triggerLdt).ToDuration().ToTimeSpan().TotalMinutes;

So my question really is 3 questions:

Why does NodaTime not have a TotalMinutes function?

Why does (1) above not work?

Is there a cleaner way to do this than (2)?

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • Are you certain you should be using local dates and times at all here? When you're talking about "total minutes between" that sounds like you're more likely to be interested in a duration than a period. In particular a "trigger" sounds like it will be something in a particular time zone, representing an instant in time. Perhaps you should be converting both values to Instants using the apprropriate time zone, and then taking the duration between them? – Jon Skeet Nov 06 '16 at 08:34

1 Answers1

5

Simply use the Period.Between static method, and specify the units you'd like the output to be represented in.

Period p = Period.Between(start, end, PeriodUnits.Minutes);
long totalMinutes = p.Minutes;

If you don't specify the PeriodUnits explicitly, it defaults to PeriodUnits.DateAndTime. This returns a Period that has all possible date and time properties (except weeks) populated, thus leaving the Minutes property having only minutes that are less than an hour.

In other words, using Period.Between without specifying units is like asking for Minutes on a TimeSpan, while specifying PeriodUnits.Minutes is like asking for TotalMinutes on a TimeSpan. You use the Minutes property of the Period either way - it just controls how the Period is constructed.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • @Jon, got your comments - thanks. Yes, this particular situation could have been done either way, but was slightly more wieldy using a duration via the ZonedDateTime/Instant pathway. So I went for the LocalDateTime/Period pathway and got hooked on a technical detail I missed. – user3152403 Dec 05 '16 at 02:55
  • this is exactly what I was looking for, and answers all three of my original questions. Appreciate your response. With Time, one does have to be real careful! – user3152403 Dec 05 '16 at 02:59
  • When I try this solution i get this exception: "Units contains time units: Minutes Parameter name: units" – Mike Murphy Nov 06 '18 at 13:46
  • 1
    @MikeMurphy - Maybe you passed `LocalDate` values instead of `LocalDateTime`? – Matt Johnson-Pint Nov 06 '18 at 15:20