# MEGA Date Formatters Tour
###### tags: `tutorials` `DateFormatter` `MEGA iOS`
## What's MEGA DateFormatter
A bunch of classes that help you to format dates according to WWDC localization topics. It helps you
- **It translates formatted date into localized date text based on device language setting.** e.g `Jan 1, 1970` in English, `1 ene 1970` in Spanish , `1970年1月1日` in Chinese all depends on the user's device.
- **It helps caching the date formatter**. As a date formatter is a bit heavy to create, which if you create within a `TableViewCell`, it's a heavy burden for CPU to create so many formatters while user scrolling. **MEGA DateFormatter** help you caching popular formatters and optimize it accessing, so it becomes very simple to access, and dispose it after using.
- **Wraps in easy to use API**. Wraps all the APIs to `DateFormatter` extension, whenever you need a date formatter, just ask for it, very simple. :astonished:
- **Supports `Calendar`, `Locale` and `TimeZone` customization.** Gives you easy access if you need custom a formatter with a different calendar, e.g. `buddhist` or `chinese`, locale, e.g `en_US` or `zh_CN`, timeZone e.g `Australia/Brisbane`.
- **Help formatting date in relative date formatting.** If you need for format a date with relative localized text for **Today**, **Tomorrow**, **Yesterday**, then **MEGA DateFormatter** helps you to format those dates with internationalization support. (Yesterday`, `Today`, `Tomorrow` / `hoy`, `mañana`, `pasado mañana` / `昨天`, `今天`, `明天`, `后天). And at the same time, it helps your format other dates out of range `[-2, +2](which depends on the locale setting)` days, it behaves just like other formatter do. :raised_hands: No need to translate those words and make it across all languages supported and no need `if date.isToday` tests for date formatting.
- **Fully tested.**
## Purpose to have a unified date formatter
- **Modular**. To have unified API interface for MEGA's project which decouples using of date formatter and creating of which, so that date formatter is easy to be updated once any changes introducing into Apple's *Formatter* API.
- **Simplify DateFormatter Creating**. Simplify development and improve performance.
- **Safer**. As the formatters are created and cached in memory, with a `DateFormatting` protocol can safely preventing developers to accidentally update a cached formatter.
## How Can I use it?
### Swift
#### Simply format a date with given style
1. Short
```swift
let formatter = DateFormatter.dateShort()
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `1/1/70`
```
2. Medium
```swift
let formatter = DateFormatter.dateMedium()
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `Jan 1, 1970`
```
3. Long
```swift
let formatter = DateFormatter.dateLong()
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `January 1, 1970`
```
4. Full
```swift
let formatter = DateFormatter.dateFull()
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `Thursday, January 1, 1970`
```
### Format a date with relative date instance
1. Short
```swift
let formatter = DateFormatter.dateRelativeShort()
formatter.localisedString(from: Date(timeIntervalSinceNow: 0)) // Today
formatter.localisedString(from: Date(timeIntervalSinceNow: 60 * 60 * 24)) // Tomorrow
formatter.localisedString(from: Date(timeIntervalSinceNow: -60 * 60 * 24)) // Yesterday
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `1/1/70`
```
2. Medium
```swift
let formatter = DateFormatter.dateRelativeMedium()
formatter.localisedString(from: Date(timeIntervalSinceNow: 0)) // Today
formatter.localisedString(from: Date(timeIntervalSinceNow: 60 * 60 * 24)) // Tomorrow
formatter.localisedString(from: Date(timeIntervalSinceNow: -60 * 60 * 24)) // Yesterday
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `Jan 1, 1970`
```
3. Long
```swift
let formatter = DateFormatter.dateRelativeLong()
formatter.localisedString(from: Date(timeIntervalSinceNow: 0)) // Today
formatter.localisedString(from: Date(timeIntervalSinceNow: 60 * 60 * 24)) // Tomorrow
formatter.localisedString(from: Date(timeIntervalSinceNow: -60 * 60 * 24)) // Yesterday
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `January 1, 1970`
```
4. Full
```swift
let formatter = DateFormatter.dateRelativeFull()
formatter.localisedString(from: Date(timeIntervalSinceNow: 0)) // Today
formatter.localisedString(from: Date(timeIntervalSinceNow: 60 * 60 * 24)) // Tomorrow
formatter.localisedString(from: Date(timeIntervalSinceNow: -60 * 60 * 24)) // Yesterday
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `Thursday, January 1, 1970`
```
#### Format a date with given locale (Spanish as example)
1. Short
```swift
let formatter = DateFormatter.dateShort(locale: Locale("es-ES"))
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `1/1/70`
```
2. Medium
```swift
let formatter = DateFormatter.dateMedium(locale: Locale("es-ES"))
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `1 ene 1970"`
```
3. Long
```swift
let formatter = DateFormatter.dateLong(locale: Locale("es-ES"))
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `1 de enero de 1970`
```
4. Full
```swift
let formatter = DateFormatter.dateFull(locale: Locale("es-ES"))
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // `Jueves, 1 de enero de 1970`
```
#### Customize your date formatter
If there is no predefined date formatter suits for you, please consult with UX designers whether they prefer to use Apple predefined date formatters, as they are
- More robust.
- Formatted text reads more native according to locale language setting.
- Supports relative formatting.
MEGA DateFormatter does support string template formatting, e.g. `d` for 1 digit `day of month`, `MM` for 2 digits zero padding if needed month as you know, however, DO REMEMBER, **Custom String Template Formatter DOES NOT SUPPORT LOCALIZATION WELL.**
> **PLEASE TRY YOUR BEST AVOID USING TEMPLATE STRING FORMATTER**
> There is a pre-defined `dateMediumWithWeekday` formatter, which is defined by string template of `EEEEMMMddyyyy` which represents epoch time as `Thursday, Jan 01, 1970`
> More information about string template, please visit unicode [Date Field Symbol Table](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table)
1. Customised Template Date Time Formatter
```swift
let formatter = DateFormatter.fromTemplate("EEEEMMMddyyyy") // Using user's phone default locale setting, assuming `en_US`
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // "Thursday, Jan 01, 1970"
let formatter = DateFormatter.fromTemplate("EEEEMMMddyyyy", locale: Locale(identifier: "es_ES"))
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // jueves, 01 de ene de 1970
let formatter = DateFormatter.fromTemplate("EEEEMMMddyyyy", locale: Locale(identifier: "zh_CN"))
formatter.localisedString(from: Date(timeIntervalSince1970: 0)) // 1970年1月01日 星期四
```
> Note: This type of formatter does **NOT** support relative formatting, e.g. `Today`, `Tomorrow`
### Objective-C
- You don't need extra steps to use this formatter in Objective-C code.
```objective-c
id<DateFormatting> formatter = [NSDateFormatter dateShortWithCalendar:nil timeZone:nil locale:nil];
NSString *formattedDate = [formatter localisedStringFrom:[NSDate dateWithTimeIntervalSince1970:0]];
```
> Note: Do not forget to import *swift header* as below
> ```
> #import "MEGA-Swift.h"
> ```
## More on the way..
The **TimeFormatter**, **TimeIntervalFormatter**, **DateComponentsFormatter**, **NumberFormatter**, **ByteCountFormatter** are under development.