date_and_time 0.0.3-alpha copy "date_and_time: ^0.0.3-alpha" to clipboard
date_and_time: ^0.0.3-alpha copied to clipboard

Clean, immutable Date and Time types. Separate types without the complexity of DateTime.

date_and_time #

This package provides Date and Time types they are clean immutable types without the complexity of DateTime.

Why Separate Date and Time? #

Dates and times usually serve distinct purposes and we often use them independently. So, it doesn't make sense to smash them together by default. Changing the time of a DateTime means making a copy of both and replacing the time, while changing the date of the DateTime also means copying both and replace the date. This is very onerous and makes code more confusing.

The other sweetener is that if you use Date.today() or Time.now(), you can easily mock the time in your tests. Mocking time in Flutter apps that depend heavily on time is very onerous because using once instance of DateTime.now() will make your tests flaky and hard to diagnose.

Dates #

Represent calendar days (birthdays, holidays, deadlines) where the time is irrelevant.

Times #

Represent a point in time for any date.

Using DateTime for these cases:

  • Adds unnecessary complexity
  • Makes comparison logic more complicated
  • Makes it harder to serialize/deserialize when you only need one component
  • Makes it harder change one value without changing the other

This package provides two extension types that solve these problems:

  • Date - For working with calendar dates
  • Time - For working with times of day

Features #

  • ✨ Pure immutable types
  • 🎯 Intuitive API design
  • 🔄 Easy conversion to and from strings
  • 🧮 Date arithmetic and time comparison
  • 🌐 UTC-first approach with local time conversion support
  • 🔄 Utility functions for common date/time operations

Timezone #

This library uses UTC by default. This is because using UTC is generally safer and local timezone should generally only be used for display purposes. All operations are performed in UTC, with convenient methods to convert to local time when needed for display.

Getting Started #

Install the package according the "Installing" tab here on Pub Dev.

Usage #

Working with Dates #

// Get today's date (in UTC)
final today = Date.today();

// Parse from string (assumes UTC)
final birthday = Date.tryParse('1990-04-15');

// Create from values (in UTC)
final date = Date.fromValues(year: 2024, month: 3, day: 15);

// Access components
print(date.year);    // 2024
print(date.month);   // 3
print(date.day);     // 15
print(date.weekday); // 5 (Friday)

// Get underlying DateTime (UTC)
final dateTime = date.asDateTime;

// Convert to local DateTime
final localDateTime = date.toLocalDateTime();

// Date arithmetic
final tomorrow = date.add(Duration(days: 1));
final yesterday = date.subtract(Duration(days: 1));

// ISO 8601 formatting
print(date.toIso8601String()); // 2024-03-15

Working with Times #

// Get current time (in UTC)
final now = Time.now();

// Create from values (in UTC)
final time = Time.fromValues(hour: 14, minute: 30, second: 15);

// Access components
print(time.hour);         // 14
print(time.minute);       // 30
print(time.second);       // 15
print(time.totalSeconds); // 52215

// Parse from string (assumes UTC)
final parsed = Time.tryParse('14:30:15');

// Compare times
final meetingTime = Time.fromValues(hour: 14, minute: 30);
final isLater = meetingTime.compareTo(now) > 0;

// ISO 8601 formatting
print(time.toIso8601String()); // 14:30:15

Utility Functions #

// Combine Date and Time into DateTime
final date = Date.today();
final time = Time.now();
final dateTime = combineDateAndTime(date, time); // Returns UTC DateTime

// Get current UTC time
final currentUtc = now; // Returns current UTC DateTime
print(nowAsIso8601); // "2024-03-20T14:30:00.000Z"

// Get current local time
final currentLocal = nowLocal; // Returns current local DateTime
print(nowLocalAsIso8601); // "2024-03-20T14:30:00.000+10:00"

Testing Support #

The package includes Zone-based time control for testing. This allows you to provide custom implementations of the current date and time. All mocked times are handled in UTC:

void main() {
  test('custom time test', () {
    final customTime = DateTime.utc(2024, 1, 1, 12, 0);
    
    runZoned(
      () {
        final now = Time.now(); // Will be in UTC
        expect(now.hour, equals(12));
        expect(now.minute, equals(0));

        final today = Date.today(); // Will be in UTC
        expect(today.year, equals(2024));
        expect(today.month, equals(1));
        expect(today.day, equals(1));
      },
      zoneValues: {nowKey: () => customTime},
    );
  });
}

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

License #

This project is licensed under the BSD-3 License - see the LICENSE file for details.

10
likes
0
points
59
downloads

Publisher

verified publisherchristianfindlay.com

Weekly Downloads

Clean, immutable Date and Time types. Separate types without the complexity of DateTime.

Repository (GitHub)
View/report issues

Topics

#date #time #datetime #testing #utilities

License

unknown (license)

More

Packages that depend on date_and_time