Repository: Alamofire/Alamofire
File: Source/ParameterEncoder.swift (Swift)

Code before:
/// This type is largely based on Vapor's [`url-encoded-form`](https://github.com/vapor/url-encoded-form) project.
public final class URLEncodedFormEncoder {
    /// Configures how `Bool` parameters are encoded.
    public enum BoolEncoding {
        /// Encodes `true` as `1`, `false` as `0`.
        case numeric
        /// Encodes `true` as "true", `false` as "false".
        case literal

        /// Encodes the given `Bool` as a `String`.
        ///
        /// - Parameter value: The `Bool` to encode.
        /// - Returns:         The encoded `String`.
        func encode(_ value: Bool) -> String {
            switch self {
            case .numeric: return value ? "1" : "0"
            case .literal: return value ? "true" : "false"
            }
        }
    }

    /// Configures how `Date` parameters are encoded.
    public enum DateEncoding {
        /// Encodes the date from `Date` structure.
        case deferredToDate
        /// Encodes the date as a UNIX timestamp.
        case secondsSince1970
        /// Encodes the date as UNIX millisecond timestamp.
        case millisecondsSince1970
        /// Encodes the date as an ISO-8601-formatted string (in RFC 3339 format).
        case iso8601
        /// Encodes the date as a string formatted by the given formatter.
        case formatted(DateFormatter)
        /// Encodes the date as a custom string formatted by the given closure.
        case custom((Date) -> String)

        /// Encodes the date according to the strategy.
        ///
        /// - Parameter string: The `Date` to encode.
        /// - Returns:          The encoded `String` or `nil` if the date should be encoded as `Encodable` structure.
        func encode(_ value: Date) -> String? {
            switch self {
            case .deferredToDate:
                return nil
            case .secondsSince1970:
                return String(value.timeIntervalSince1970)
            case .millisecondsSince1970:
                return String(value.timeIntervalSince1970 * 1000.0)
            case .iso8601:
                return ISO8601DateFormatter.string(from: value,
                                                   timeZone: TimeZone(secondsFromGMT: 0)!,

Review comment (suggestion):
This should be more precise, like `JSONEncoder`'s: "Encodes dates as seconds since midnight UTC on January 1, 1970.".

Code after:
/// This type is largely based on Vapor's [`url-encoded-form`](https://github.com/vapor/url-encoded-form) project.
public final class URLEncodedFormEncoder {
    /// Configures how `Bool` parameters are encoded.
    public enum BoolEncoding {
        /// Encodes `true` as `1`, `false` as `0`.
        case numeric
        /// Encodes `true` as "true", `false` as "false".
        case literal

        /// Encodes the given `Bool` as a `String`.
        ///
        /// - Parameter value: The `Bool` to encode.
        /// - Returns:         The encoded `String`.
        func encode(_ value: Bool) -> String {
            switch self {
            case .numeric: return value ? "1" : "0"
            case .literal: return value ? "true" : "false"
            }
        }
    }

    /// Configures how `Date` parameters are encoded.
    public enum DateEncoding {
        /// Defers encoding to the `Date` type.
        case deferredToDate
        /// Encodes dates as seconds since midnight UTC on January 1, 1970.
        case secondsSince1970
        /// Encodes dates as milliseconds since midnight UTC on January 1, 1970.
        case millisecondsSince1970
        /// Encodes dates according to the ISO 8601 and RFC3339 standards.
        case iso8601
        /// Encodes dates using the given `DateFormatter`.
        case formatted(DateFormatter)
        /// Encodes dates using the given closure.
        case custom((Date) throws -> String)

        private static let iso8601Formatter: ISO8601DateFormatter = {
            let formatter = ISO8601DateFormatter()
            formatter.formatOptions = .withInternetDateTime
            return formatter
        }()

        /// Encodes the date according to the strategy.
        ///
        /// - Parameter string: The `Date` to encode.
        /// - Returns:          The encoded `String` or `nil` if the date should be encoded as `Encodable` structure.
        func encode(_ value: Date) throws -> String? {
            switch self {
            case .deferredToDate:
                return nil
            case .secondsSince1970: