Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define valid date, time and recurrence values #3710

Open
Necior opened this issue Nov 28, 2024 · 7 comments
Open

Define valid date, time and recurrence values #3710

Necior opened this issue Nov 28, 2024 · 7 comments

Comments

@Necior
Copy link
Contributor

Necior commented Nov 28, 2024

It is not clear what constitutes valid date, time and recurrence values in Taskwarrior. Consequently, it is not clear what behavior users should expect when values fall outside of these (underspecified) ranges.

https://taskwarrior.org/docs/dates/#rcdateformat mentions that Y in Y-M-D is a 4-digit year. A different part of this page defines later and someday as "Local 9999-12-30, with time 00:00:00". It gives an impression that Taskwarrior should support dates at least up to 9999-12-30.

In practice, there are bugs like #81. Because Taskwarrior uses types whose ranges are implementation defined (e.g. int in C++), and because it seems like different parts of the codebase have different idea of what is valid, and because it is not clear what the expected behavior is, resolving these issues is non-trivial.

As a user, I would like to know what the minimum and maximum supported date is. Can I depend on Taskwarrior to work with dates after the year 2038? After 2106? 9999? Are the supported values the same, no matter what machine and C++ compiler I am using?

If a date goes over (or under, for that matter) the supported range, how will Taskwarrior behave? Will it inform me? Will it silently drop tasks with unrepresentable dates? Will it round the dates to the nearest representable values? Will it corrupt the database? Something else entirely?

Before a decision is made, I encourage you to share your perspectives, ideas, worries, proposals and insights.

@Necior
Copy link
Contributor Author

Necior commented Nov 28, 2024

To kickstart the discussion, let me share some thoughts.

Support years up to 9999

Let's start with what I believe is noncontroversial. Taskwarrior should not limit valid years to values smaller than 2038. See https://en.wikipedia.org/wiki/Year_2038_problem for extra context why 2038 is special.

2038 is less than 14 years away, while Taskwarrior itself is already 16 years old. Given that users schedule tasks for the future, I expect more and more people to encounter bugs because of the year 2038 problem.

A common solution to the above problem is using wider integers. Using 64 bits to represent the number of seconds since the Unix epoch would extend the range to hundreds of billions of years.

Should Taskwarrior support such distant dates? It's not only extra work to implement correct parsing or formatting of such dates, but it also burdens tooling around Taskwarrior with extra complexity. If a tool supports only years with 4 digits (which is a common case; Python's datetime module handles years from 0001 to 9999), it won't necessarily be able to work with all Taskwarrior tasks.

I suppose the need for tasks with dates after the year 9999 is minimal but maybe there is someone out there who uses Taskwarrior to keep track of tasks in a space colony simulation? If so, please share! :)

Given that, I think the maximum supported year should be 9999.

(I'm not sure what the minimum year should be. 0? 1? 1970?)

Warn when trying to create a date out of range

There are multiple ways in which Taskwarrior might try to craft a value outside of the agreed range. They include: parsing user supplied data (task add, task import), setting a due date with a relative offset (task add due:9000years), or recurrence. What should be done in such cases?

Data loss is highly undesirable -- database corruptions should be considered critical bugs.

Ideally, Taskwarrior would inform the user about such cases. This could be yet another "nag" message. Such a message would be preferably actionable, e.g. "The next occurrence of the task template 42 would be after 9999-12-31. Taskwarrior doesn't handle such dates. Run (…) to remove the template; run (…) to change recurrence to a smaller value."

@djmitche
Copy link
Collaborator

It is worth noting that #81 was about overflowing an int delta . The Datetime value itself uses time_t which on 64-bit systems is 64 bits.

I don't have much opinion as to how to resolve this, but I will note that 32-bit systems are very unusual these days and I think it's reasonable to leave those behind, or accept sub-optimal behavior on those systems.

@djmitche
Copy link
Collaborator

Oh, one other important point: per the TaskChampion docs any task is a valid task. That means Taskwarrior shouldn't crash or fail on any task that it happens to find in the task DB. That's not the case right now -- it's pretty easy to find cases where an "invalid" value for a property will cause exceptions. But, we shouldn't make it worse. So any decision about validity when reading from the taskdb needs to fallback to a reasonable default, rather than failing.

@Necior
Copy link
Contributor Author

Necior commented Nov 29, 2024

I will note that 32-bit systems are very unusual these days

I use a 32-bit machine :) In general, older Raspberry Pi models are 32-bit and they seem somewhat popular in the self-hosting space.

Anyway, what I tried to ask is more user-centric. As a user, I don't really care what's the task model internally. I want to know what I can expect from the software as a product.

@tbabej
Copy link
Member

tbabej commented Nov 29, 2024

The expectation is that we officially support any datetime until 9999-12-31. Datetimes after that date are not supported as we would have to deal with 5-digit years, which is added work for, well, arguably very little benefit of anyone alive today 😛

This is part of official feature set as of 2.6.0:

$ task news 2.6.0 all

(1/7) Support for 64-bit timestamps and numeric values

  What changed in 2.6.0?
  Taskwarrior now supports 64-bit timestamps, making it possible to set due dates
  and other date attributes beyond 19 January 2038 (limit of 32-bit timestamps).

  The current limit is 31 December 9999 for display reasons (last 4-digit year).

  What was the motivation behind this feature?
  With each year passing by faster than the last, setting tasks for 2040s
  is not as unfeasible as it once was.

  What do I have to do?
  Don't forget that 50-year anniversary and 'task add' a long-term task today!

@djmitche
Copy link
Collaborator

@Necior can you confirm that time_t is 64 bit on those rPi's?

@Necior
Copy link
Contributor Author

Necior commented Dec 1, 2024

Thanks for the context @tbabej! I wasn't aware of this.


@djmitche, I wasn't clear enough. The 32-bit machine I use is not a Raspberry Pi (it's a 32-bit MIPS for which g++ 13.2.0 generates code with 32-bit size_t and 64-bit time_t). I meant to say that Pis are popular in general and the older ones are 32-bit.

But I don't think this is the key point here.

If we know the values we want to represent, we can avoid types whose ranges are implementation defined and not necessarily large enough (e.g. int in some contexts) and use more concrete types (e.g. fixed width integers like int64_t).


My motivation for this discussion is two-fold.

First, it's to clear up what users can expect from Taskwarrior. Does it work on $someOS? Is it okay to use years-long recurrence intervals? Does Taskwarrior handle dates that are decades into the future?

Second, it's to make it clear to contributors how to write code. For C++, what is the standard the project uses? (It's documented to be C++17 and that's great it is documented! It was helpful to me already.) Do we make any assumptions about the operating system? About architecture? About sizes of some C++ types?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Backlog
Development

No branches or pull requests

3 participants