Migration Guide¶
This guide helps you migrate from other datetime libraries to Carbonic.
From Python's datetime¶
Carbonic builds on Python's standard library while providing a more fluent API.
Standard Library Compatibility¶
New in 1.0.2: Carbonic classes are now fully compatible with Python's standard library datetime types. You can use Carbonic objects anywhere stdlib datetime objects are expected.
import datetime
from carbonic import Date, DateTime, Duration
# Date is compatible with datetime.date
carbonic_date = Date(2024, 1, 15)
native_date = datetime.date(2024, 1, 15)
# All properties work
print(f"Properties: {carbonic_date.year}, {carbonic_date.month}, {carbonic_date.day}")
# All methods work
print(f"Weekday: {carbonic_date.weekday()}")         # 0 (Monday)
print(f"ISO format: {carbonic_date.isoformat()}")    # "2024-01-15"
# Direct comparison works
print(f"Equal to native: {carbonic_date == native_date}")                      # True
print(f"Less than 2024-01-16: {carbonic_date < datetime.date(2024, 1, 16)}")  # True
# DateTime is compatible with datetime.datetime
carbonic_dt = DateTime(2024, 1, 15, 14, 30, 45, tz="UTC")
native_dt = datetime.datetime(2024, 1, 15, 14, 30, 45, tzinfo=datetime.timezone.utc)
# All properties and methods work
print(f"Time components: {carbonic_dt.hour}:{carbonic_dt.minute}:{carbonic_dt.second}")
print(f"Timestamp: {carbonic_dt.timestamp()}")
# Direct comparison works
print(f"DateTime equal: {carbonic_dt == native_dt}")  # True
# Duration is compatible with datetime.timedelta (when no calendar components)
carbonic_dur = Duration(days=1, hours=2, minutes=30)
native_td = datetime.timedelta(days=1, hours=2, minutes=30)
# Properties match
print(f"Duration parts: days={carbonic_dur.days}, seconds={carbonic_dur.seconds}")
print(f"Total seconds: {carbonic_dur.total_seconds()}")
# Direct comparison works
print(f"Duration equal: {carbonic_dur == native_td}")  # True
This means you can:
- Pass Carbonic objects to functions expecting stdlib types
- Compare Carbonic objects directly with stdlib objects
- Access all stdlib properties and methods on Carbonic objects
- Maintain full type compatibility at runtime
Basic Object Creation¶
Date Arithmetic¶
from carbonic import DateTime, Duration
dt = DateTime(2024, 1, 15, 14, 30, tz="UTC")
# Add time - multiple ways
future1 = dt + Duration(days=7, hours=2)
future2 = dt.add_days(7).add_hours(2)
# Rich date operations
next_month = dt.add_months(1)
end_of_month = dt.end_of_month()
next_friday = dt.next(Period.FRIDAY)
Formatting¶
from carbonic import DateTime
dt = DateTime(2024, 1, 15, 14, 30, tz="UTC")
# Multiple format methods
formatted = dt.format("Y-m-d H:i:s")  # Carbon-style
iso_format = dt.to_iso_string()
date_only = dt.to_date_string()
time_only = dt.to_time_string()
# Still supports strftime
strftime_format = dt.strftime("%Y-%m-%d %H:%M:%S")
Timezone Handling¶
from carbonic import DateTime
# Create timezone-aware (encouraged)
utc_dt = DateTime(2024, 1, 15, 14, 30, tz="UTC")
# Convert timezone (fluent)
ny_dt = utc_dt.to_timezone("America/New_York")
# Naive datetime (discouraged but supported)
naive = DateTime(2024, 1, 15, 14, 30, tz=None)
aware = naive.assume_timezone("UTC")
From Arrow¶
Arrow users will find Carbonic familiar with some improvements.
Object Creation¶
Fluent Operations¶
Formatting and Humanizing¶
From Pendulum¶
Pendulum users will appreciate Carbonic's similar philosophy with stdlib focus.
Basic Usage¶
Periods and Durations¶
from carbonic import DateTime, Duration
dt = DateTime(2024, 1, 15, 14, 30, tz="UTC")
# Add time (fluent or duration objects)
future = dt.add_months(1).add_days(2).add_hours(3)
future_alt = dt + Duration(days=2, hours=3)  # months need special handling
# Subtract time
past = dt.subtract_weeks(2)
# Duration between dates
diff = dt2 - dt1  # Returns Duration object
Common Migration Patterns¶
Error Handling¶
Working with Business Days¶
Batch Operations¶
Performance Considerations¶
When Coming from Arrow/Pendulum¶
# These libraries have some overhead for convenience
# Carbonic aims to be faster while maintaining ease of use
# For bulk operations, consider:
from carbonic import DateTime
# Example data for demonstration
many_iso_strings = ["2024-01-01T00:00:00Z", "2024-01-02T00:00:00Z"]
# Instead of parsing many strings:
dates = [DateTime.parse(s) for s in many_iso_strings]
# Consider creating once and using arithmetic:
base_date = DateTime(2024, 1, 1, tz="UTC")
dates = [base_date.add(days=i) for i in range(5)]  # Generate 5 dates for example
Memory Usage¶
# Carbonic uses __slots__ for memory efficiency
from carbonic import DateTime
# Each DateTime object is lightweight
dt = DateTime.now()
print(dt.__slots__)  # ('_dt',)
# Compared to regular objects, this uses less memory
# Important for applications handling many datetime objects
Migration Checklist¶
When migrating to Carbonic:
- [ ] Update imports: Change to from carbonic import DateTime, Date, Duration
- [ ] Review timezone handling: Ensure all datetimes are timezone-aware
- [ ] Update method calls: Use Carbonic's fluent method names
- [ ] Check error handling: Update exception types
- [ ] Test thoroughly: Verify behavior matches expectations
- [ ] Install optional dependencies: Consider carbonic[fast]for performance
- [ ] Update type annotations: Use Carbonic types for better type checking
Getting Help¶
If you're migrating and run into issues:
- Check the API reference: API Documentation
- Look at examples: Common Tasks
- File an issue: GitHub Issues
- Ask questions: Use GitHub Discussions for help
The Carbonic community is happy to help with migration questions!