Skip to content

Move DateTime constants for month and weekday into extension types. #60669

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

Open
mmcdon20 opened this issue May 3, 2025 · 7 comments
Open

Move DateTime constants for month and weekday into extension types. #60669

mmcdon20 opened this issue May 3, 2025 · 7 comments
Assignees
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. feature-dot-shorthands Implementation of the dot shorthands feature. library-core type-enhancement A request for a change that isn't a bug

Comments

@mmcdon20
Copy link

mmcdon20 commented May 3, 2025

Currently DateTime has the following definition:

class DateTime implements Comparable<DateTime> {
  // Weekday constants that are returned by [weekday] method:
  static const int monday = 1;
  static const int tuesday = 2;
  static const int wednesday = 3;
  static const int thursday = 4;
  static const int friday = 5;
  static const int saturday = 6;
  static const int sunday = 7;
  static const int daysPerWeek = 7;

  // Month constants that are returned by the [month] getter.
  static const int january = 1;
  static const int february = 2;
  static const int march = 3;
  static const int april = 4;
  static const int may = 5;
  static const int june = 6;
  static const int july = 7;
  static const int august = 8;
  static const int september = 9;
  static const int october = 10;
  static const int november = 11;
  static const int december = 12;
  static const int monthsPerYear = 12;

  ...
  external int get weekday;
  external int get month;
  ...
}

I propose that we deprecate the constants in DateTime and create extension types to represent the Month and Weekday.

class DateTime implements Comparable<DateTime> {
  ...
  external Weekday get weekday;
  external Month get month;
  ...
}

extension type const Weekday(int _) implements int {
  // Weekday constants that are returned by [weekday] method:
  static const Weekday monday = Weekday(1);
  static const Weekday tuesday = Weekday(2);
  static const Weekday wednesday = Weekday(3);
  static const Weekday thursday = Weekday(4);
  static const Weekday friday = Weekday(5);
  static const Weekday saturday = Weekday(6);
  static const Weekday sunday = Weekday(7);
  static const int daysPerWeek = 7;
}

extension type const Month(int _) implements int {
  // Month constants that are returned by the [month] getter.
  static const Month january = Month(1);
  static const Month february = Month(2);
  static const Month march = Month(3);
  static const Month april = Month(4);
  static const Month may = Month(5);
  static const Month june = Month(6);
  static const Month july = Month(7);
  static const Month august = Month(8);
  static const Month september = Month(9);
  static const Month october = Month(10);
  static const Month november = Month(11);
  static const Month december = Month(12);
  static const int monthsPerYear = 12;
}

The reason for this change is to better enable the upcoming dot-shorthands feature.

The proposed change would allow us to write for example:

void main() {
  if (DateTime.now() case DateTime(weekday: .saturday || .sunday)) {
    print('today is a weekend');
  } else {
    print('today is a weekday');
  }
}
@lrhn
Copy link
Member

lrhn commented May 3, 2025

Could work. Would probably still be available in DateTime for backwards compatibility.
Like the idea.

@lrhn lrhn added area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core type-enhancement A request for a change that isn't a bug feature-dot-shorthands Implementation of the dot shorthands feature. labels May 3, 2025
@lrhn lrhn self-assigned this May 3, 2025
@RohitSaily
Copy link
Contributor

RohitSaily commented May 4, 2025

Can't we implement the various units as extension types without breaking backwards compatibility? It should work if we keep the identifiers the same and the different units still implement int. eg

class DateTime implements Comparable<DateTime> {
  ...
  static const Weekday monday = Weekday(1);
  static const Weekday tuesday = Weekday(2);
  static const Weekday wednesday = Weekday(3);
  static const Weekday thursday = Weekday(4);
  static const Weekday friday = Weekday(5);
  static const Weekday saturday = Weekday(6);
  static const Weekday sunday = Weekday(7);

  static const Month january = Month(1);
  static const Month february = Month(2);
  static const Month march = Month(3);
  static const Month april = Month(4);
  static const Month may = Month(5);
  static const Month june = Month(6);
  static const Month july = Month(7);
  static const Month august = Month(8);
  static const Month september = Month(9);
  static const Month october = Month(10);
  static const Month november = Month(11);
  static const Month december = Month(12);
  ...
}

Any computations which processed the units as int would still work, and new ones could use the specialized types for better safety, all while maintaining backwards compatability

@mmcdon20
Copy link
Author

mmcdon20 commented May 4, 2025

@RohitSaily

The constants still need to be defined inside the Weekday or Month type for the dot-shorthand to work.

But you could update the types of the existing constants also.

@RohitSaily
Copy link
Contributor

@mmcdon20 that makes sense that both would have to be done 👍

@lrhn @mmcdon20 I wouldn't mind attempting this change if neither of you are working on it. Let me know, I wouldn't want to do any redundant work

@lrhn
Copy link
Member

lrhn commented May 5, 2025

The problem here is that changing the parameter type to Month will break existing code which passes in an int.

We can make Month implement int, but a call of DateTime(1970, 1, 1) would become invalid, because int is not a Month.

If we don't change the parameter type, and keep it as int, then dot shorthands won't work unless the Month constants are also constants on int.
They don't belong on int, and there is no implicit coercion from int to Month, and no static extension that can put the constants on int.

So, sadly it's not possible with the current feature-set, not without breaking far too much code.

@RohitSaily
Copy link
Contributor

You are correct, I only considered usages of the constants directly. It would be very breaking to make the changes because int values could have been used from other places.

So it would only make sense to do as @mmcdon20 originally proposed, and add the new types while keeping the original class as it is. Then new constructors, methods, etc would have to be added to DateTime or current ones can be updated to optionally accept the new types as inputs.

@mmcdon20
Copy link
Author

mmcdon20 commented May 6, 2025

We can make Month implement int, but a call of DateTime(1970, 1, 1) would become invalid, because int is not a Month.

So, sadly it's not possible with the current feature-set, not without breaking far too much code.

Thats unfortunate. I think it can be made to work with any of the following, but some of these might work better than others:

  1. implicit conversions (Implicit coercion through implicit constructors. language#3704, Implicit Constructor proposal language#108)
  2. union types (Sum/union types and type matching language#83)
  3. method overloading (Support method/function overloads language#1122)
  4. static extensions (Static extension methods language#723)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. feature-dot-shorthands Implementation of the dot shorthands feature. library-core type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

3 participants