<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8">
</head>
<body>
<div style="font-family:sans-serif"><div style="white-space:normal"><p dir="auto">Hi Pitiphong,</p>
<p dir="auto">Thanks for taking the time and energy to pitch this, too! If we can find a good solution for matching this up with ISO 8601, and we have high demand for this feature, I think it will be worth reconsidering again in the future.<br>
Thanks for the input!</p>
<p dir="auto">— Itai</p>
<p dir="auto">On 8 Sep 2017, at 13:00, Pitiphong Phongpattranont wrote:</p>
</div>
<blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><div id="E6E832A2-1B32-44C0-93B7-07D266CC4442"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">Hi Itai,</div><div class=""><br class=""></div><div class="">As I told you in my last email that I’m thinking about the ISO 8601 case. After thinking about that, having a discussion in the Swift Evolution and reading your emails, I think it may not worth to add this into Swift Standard Library. I think the use case is not that much so it’s not worth the cost of maintenance alone not to mention or think about how to implement it properly (if we choose to do and support the `iso8601` strategy.</div><div class=""><br class=""></div><div class="">I think I will close this pitch and would like to thank you for reviewing and discussing on this.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">— Pitiphong P.</div><div><br class=""><blockquote type="cite" class=""><div class="">On 7 Sep BE 2560, at 01:03, Itai Ferber &lt;<a href="mailto:iferber@apple.com" class="">iferber@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class="">


<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8" class="">

<div class="">
<div style="font-family:sans-serif" class=""><div style="white-space:normal" class=""><p dir="auto" class="">Hi Pitiphong,</p><p dir="auto" class="">Don’t worry — your original email was clear, and we are on the same page about <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date{En,De}codingStrategy</code> and <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents{En,De}codingStrategy</code> being separate things.<br class="">
To clarify my points, though, there are two main things I want to say:</p>

<ol class="">
<li value="1" class="">I think there is a mismatch here between your goal of representing the components of a date (and what <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> can specifically hold) and the goal of ISO 8601</li>
<li value="2" class="">I think that there is an inherent problem in parsing <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> due to ambiguity</li>
</ol><p dir="auto" class="">I think both of these issues can be solved by reading and writing a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code> (formatted however you need it to be) instead of <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code>.</p><p dir="auto" class="">To elaborate:</p>

<ul class="">
<li class=""><p dir="auto" class=""><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> is meant to be a container for an <em class="">arbitrary</em> subset of information about a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code>. A <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code> represents a specific instant in time, but <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> are effectively meaningless without additional context. In the examples that you give, it’s possible to represent the concepts at hand with <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code>, but in order to make those components actionable and meaningful, you still need to convert them to <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code>s. Note also that:</p>

<ul class="">
<li class="">It’s entirely possible to create a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> which represents a date which does not exist, or a time which does not exist</li>
<li class="">Any of these concepts can also be represented by a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code> instead of just components; e.g., an all-day event can be represented by a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code> that represents the beginning of the day (<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">00:00:00</code>) and a flag that indicates that the time of the event can be ignored, or by a start <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code> that represents the start of the day and and end <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code> that represents the end of the day</li>
</ul></li>
<li class=""><p dir="auto" class="">Unlike <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code>, ISO 8601 strings have some structure to them. They cannot represent just a time zone, for instance, or some singular components of a date/time (e.g. a month without a year, a day without a month and year, a minute without an hour, a second without a minute and hour, etc.). I think this is a relatively large conceptual mismatch that is worth considering deeply. There are a lot of <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> instances which simply cannot be represented by an ISO 8601 string</p></li>
<li class=""><p dir="auto" class="">There is also the issue of decoding arbitrary ISO 8601 strings into <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code>. <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code>, having no structure at all, have no specified format they can expect to decode from, and ISO 8601 does not always provide that structure. Consider the following example:</p>

<ul class="">
<li class="">ISO 8601 allows for date representations by year, month, and day (<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">YYYY-MM-DD</code>), among other forms. But it also allows days to be left unspecified (<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">YYYY-MM</code>), and even months (<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">YYYY</code>)</li>
<li class="">Similarly, it allows for a time representations by hour, minute, and second (<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">hh:mm:ss</code>), but also just hour and minute (<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">hh:mm</code>), and just hour (<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">hh</code>). Importantly, it allows time separators to be omitted (<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">hhmmss</code>, <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">hhmm</code>, <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">hh</code>)</li>
<li class="">Consider then, attempting to parse the string <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">"2017"</code> without any context — what <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> should be read out? Intuitively, <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">2017</code> looks like a year (<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">YYYY</code>), but it is equally valid to parse as the time <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">20:17</code> (<code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">hhmm</code>). Without knowing the expected format, parsing is ambiguous</li>
</ul><p dir="auto" class="">We cannot promise to parse <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> in all cases because there are many combinations of strings that are just completely ambiguous. </p></li>
<li class=""><p dir="auto" class="">So, to get at the core of this — if there is a specific format that you would like to encode to and from, why not do so with a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code> and a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateFormatter</code> (or if you need ISO 8601 specifically, <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">ISO8601DateFormatter</code>)? With a formatter, the format is unambiguous because you explicitly provide it, and there is nothing the date can’t represent that <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> can. You can always parse the date and pull out only those components that you care about. You also mention interoperability with an external JSON source — how is that source producing a string/parsing one back? [What I’m getting at here is: what is the value of adding a new, potentially risky strategy over existing methods that might work just as well, or better?]</p></li>
<li class=""><p dir="auto" class="">And lastly, if <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">.iso8601</code> is not necessarily a good fit for this strategy, what separates <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">.custom</code> from just overriding <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">encode(to:)</code> and <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">init(from:)</code> and writing the components out in the format that you need?</p></li>
</ul><p dir="auto" class="">I think answers to these questions can help us push this forward. :)</p><p dir="auto" class="">— Itai</p><p dir="auto" class="">On 5 Sep 2017, at 10:41, Pitiphong Phongpattranont wrote:</p>

</div>
<div style="white-space:normal" class=""></div>
<blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px" class=""><div id="0AA36A42-DC6C-4D81-88FB-6C1EA9BC207C" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Itai,<div class=""><br class=""></div><div class="">I think my first pitch email was not clear enough and want to sorry for that. I have been working on a calendar app for awhile and understand the concept of calendar or date and time programming in some level. I didn’t pitch the idea of encoding and decoding `Date` value with this `DateComponents{Encoding/Decoding}Strategy`. I still agree that `Date` value should be encoded/decoded with the `Date{Encoding/Decoding}Strategy`. The DateComponents{Encoding/Decoding}Strategy I pitched only apply for `DateComponents` value only.</div><div class=""><br class=""></div><div class="">About the use case, I think there are some application which store an information of a `Date` value that is not include a time value (A date of September 6th, 2017) for example a calendar app which want to store the Start and End date of an `All Day Event` with a value of DateComponents type or an alarm app which want to store just a time of the day that user want to set an recurring alarm (10:30am.)</div><div class=""><br class=""></div><div class="">The problem I found with the current implementation is that I have no control on how the DateComponents implement the conformance methods of the Encodable and Decodable protocol. This means that if I have a service that serialize those properties with a difference notation (ISO 8601 in my case) then I cannot rely on the auto synthesized implementation from the compiler and need to do a manual encoding/decoding by manually implement the Encodable and Decodable</div><div class=""><br class=""></div><div class="">Lastly, on the issue that `ISO8601` standard does not support every components in DateComponents, I still haven’t thought this though and still thinking about it. I want to pitch the idea first and would like to have a discussion/brainstorm on should we do this and how we can do it. My backup plan is doesn’t include the `iso8601` strategy but still have the `custom` strategy for those who need to apply a custom encoding/decoding strategy which will be apply to all values in a payload. Since we encode/decode a JSON from one source at a time and the encoding/decoding strategy of DateComponents of that source should be consistency throughout its types (which may be the types that I own or the types from a 3rd party service), I think this still is a valid use case for providing a custom strategy.</div><div class=""><br class=""></div><div class="">Thank you</div><div class="">— Pitiphong P.</div><div class=""><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On 6 Sep BE 2560, at 00:15, Itai Ferber &lt;<a href="mailto:iferber@apple.com" class="">iferber@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class="">


<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8" class="">

<div class="">
<div style="font-family:sans-serif" class=""><div style="white-space:normal" class=""><p dir="auto" class="">Hi Pitiphong,</p><p dir="auto" class="">Thanks for pitching this! My main question here is about the use case. Since encoding/decoding strategies apply to all values in a payload (whether or not those belong to types that you own), they inherently come with some risk.<br class="">
What is the use case in mind for needing to encode and decode <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> directly, as opposed to encoding and decoding a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code> instance and pulling the components you need from that?</p><p dir="auto" class="">From a correctness standpoint, I also want to point out that <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> is really just a "bag of stuff" that doesn’t necessarily mean much until converted into a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code> through a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Calendar</code> and a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">TimeZone</code>. There is somewhat of a mismatch between this "bag of stuff" and what ISO 8601 intends to represent — an actual date and time. It’s possible to represent things in a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> that don’t really make sense for (or are not supported by) ISO-8601-formatted dates. For instance, you can have a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> which just has a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">TimeZone</code>, but ISO 8601 does not allow representing a time zone without a corresponding time. <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">DateComponents</code> also, for instance, has a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">quarter</code> component (among others) which I’m almost certain ISO 8601 has no equivalent for.</p><p dir="auto" class="">Given that conceptual mismatch, I think we’d need a very compelling use case to support this over simply using <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7" class="">Date</code>.</p><p dir="auto" class="">— Itai</p><p dir="auto" class="">On 3 Sep 2017, at 0:55, Pitiphong Phongpattranont via swift-evolution wrote:</p>

</div>
<div style="white-space:normal" class=""><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px" class=""><p dir="auto" class="">Hi folks, I have an idea on improving the JSON{Encoder/Decoder} to pitch.<br class="">
<br class="">
Since JSON doesn’t have a native representation for `DateComponents` like it doesn’t have for `Date` too so that there’re many ways to represent it in JSON, for example ISO 8601, UNIX timestamp, etc. for Date. There are also a few ways to represent `DateComponents` too, for example ISO 8601 (<a href="https://en.wikipedia.org/wiki/ISO_8601" style="color:#777" class="">https://en.wikipedia.org/wiki/ISO_8601</a>) also describes how to represent some of the valid date components (e.g. "2017-09-03”).  Unlike what JSON{Encoder/Decoder} does to represent `Date` value with several strategy but there is no support like that for `DateComponents`.<br class="">
<br class="">
The current implementation DateComponents is to encode/decode with KeyedContainer and cannot provide a custom or ISO 8601 compatible implementation. So I think JSON{Encoder/Decoder} should have a strategy for encoding/decoding `DateComponents` just like for Date<br class="">
<br class="">
Here’s an initial `DateComponentsStrategy` strategy that I want JSON{Encoder/Decoder}  I can think of now, any suggestion is welcomed.<br class="">
<br class="">
```swift<br class="">
  /// The strategy to use for encoding `DateComponents` values.<br class="">
  public enum DateComponentsStrategy {<br class="">
    /// Defer to `Date` for choosing an encoding. This is the default strategy.<br class="">
    case deferredToDateComponents<br class="">
<br class="">
    /// Encode the `Date` as an ISO-8601-formatted string (in RFC 3339 format).<br class="">
    case iso8601<br class="">
<br class="">
    /// Encode the `Date` as a custom value encoded by the given closure.<br class="">
    ///<br class="">
    /// If the closure fails to encode a value into the given encoder, the encoder will encode an empty automatic container in its place.<br class="">
    case custom((DateComponents, Encoder) throws -&gt; Void)<br class="">
  }<br class="">
```<br class="">
<br class="">
What do you guys think about this pitch?<br class="">
<br class="">
<br class="">
Pitiphong Phongpattranont<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="color:#777" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></p>
</blockquote></div>
<div style="white-space:normal" class="">
</div>
</div>
</div>

</div></blockquote></div><br class=""></div></div></div></blockquote>
<div style="white-space:normal" class="">
<blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px" class="">
</blockquote></div>
<div style="white-space:normal" class="">
</div>
</div>
</div>

</div></blockquote></div><br class=""></div></div></div></div></blockquote>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px">
</blockquote></div>
</div>
</body>
</html>