BDAY without year for VCARD 3.0 if server drops property X-APPLE-OMIT-YEAR



  • While trying to get support for BDAY fields with partial dates (no year) for CardBook working in a way similar to how DAVx5 handles this, I found that some servers (e.g. my Sabre/Kolab installation) seem to drop the property X-APPLE-OMIT-YEAR that DAVx5 adds to the BDAY field. This leads to the following problem:

    1. When you create a contact with a partial birth date on one device,
    2. synchronize to the server, and
    3. sync the contact back to another device (both using DAVx5),

    the second device will show the birth year as 1604 (instead of no year). The reason for this is that DAVx5 treats the year 1604 in the BDAY field as an actual year if there is no property X-APPLE-OMIT-YEAR defining that year as invalid.

    While this is mainly an issue of the server not supporting a non-standard extension (X-APPLE-OMIT-YEAR), I believe that DAVx5 should take care of this situation. I propose that DAVx5 always treats the year 1604 (first year of the Gregorian calendar) as a placeholder for an empty year in a partial date.

    Related:


  • developer

    Hello,

    Thanks for your message about partial date support.

    @michaelroland said in BDAY without year for VCARD 3.0 if server drops property X-APPLE-OMIT-YEAR:

    While this is mainly an issue of the server not supporting a non-standard extension (X-APPLE-OMIT-YEAR), I believe that DAVx5 should take care of this situation. I propose that DAVx5 always treats the year 1604 (first year of the Gregorian calendar) as a placeholder for an empty year in a partial date.

    Wouldn’t that cause data loss for a vCard of – for instance – Anna Francisca de Bruyns?

    How can we know whether BDAY:1604-01-01 means 1 January 1604 or just 1 January if we don’t care about the presence of X-APPLE-OMIT-YEAR?

    My personal opinion: vCard 3 doesn’t support partial dates, and if a server drops the workaround (namely X-APPLE-OMIT-YEAR), partial dates are not doable in this environment. That’s why vCard 4 (and ugly workarounds like X-APPLE-OMIT-YEAR) have been invented 🙂



  • The issue here is that DAVx5 uses an ugly workaround to get partial dates to work but it does not accept the potential consequences and treats values that it sends (and have been sanitized by the server) in a different way when receiving them again. Apple, for instance, seems to have accepted that and treats 1604 (even without the X-APPLE-OMIT-YEAR property) as a non-year (i.e. partial date).

    Also, since DAVx5 already has issues with other dates (e.g. years 0000 and 0001 are treated as non-years), I would consider the loss of information for another year that typically never occurs in a list of contacts a rather low price to pay.


  • developer

    @michaelroland said in BDAY without year for VCARD 3.0 if server drops property X-APPLE-OMIT-YEAR:

    The issue here is that DAVx5 uses an ugly workaround to get partial dates to work but it does not accept the potential consequences and treats values that it sends (and have been sanitized by the server) in a different way when receiving them again.

    I agree that this should not happen. In which case are sent values treated differently then received ones?

    If you mean “removing the X-… property” by “sanitizing”, I don’t agree. As far as I understand it, vCard 3 partial dates are impossible to implement with servers which remove extended properties. Or, in other words, those requirements are incompatible:

    • only vCard 3 supported → problem already solved in vCard 4 since August 2011
    • support for partial dates in vCard 3 (can only be an [ugly] workaround; with an extended property)
    • no data loss or other disadvantages with conformant implementations → would happen if there was a default value for X-APPLE-OMIT-YEAR (also, should this workaround also be applied for vCard 4 etc.? Because maybe the data have just been upgraded from vCard 3 to vCard 4? Etc. etc., it gets only more and more complicated.)

    Personally, I wouldn’t put much efforts into working around a problem which has already been solved 8 years ago, and where a workaround for older implementation exists, just because some servers remove the workaround.

    Which servers are you specifically talking about? Maybe they can be improved so that they understand vCard 4 or at least don’t strip extended properties (at least in BDAY)?



  • The server, unfortunately, cannot be “improved” in that case. Anyways, I don’t see a need for that since it speaks vCard 3.0 perfectly fine and I can (more or less) live with the featureset of vCard 3.0.

    The problem that I see here is that DAVx5 uses a nasty hack (borrowed from Apple) to add a feature to vCard 3.0 (namely partial dates). The hack relies of the fact that some servers don’t sanitize inputs and allow the invalid property X-APPLE-OMIT-YEAR to be set on the BDAY field. Now, if a server properly sanitizes its inputs and removes the invalid (disallowed) property from the BDAY field, DAVx5 suddenly treats the date value in a different way (obviously, because it expectes the property X-APPLE-OMIT-YEAR).

    Hence, in my opinion, DAVx5 shouldn’t have allowed partial dates for vCard 3.0 in the first place, as the implementation of the feature actually introduces a violation of the vCard 3.0 specification (i.e. a bug). But since DAVx5 does implement the feature, it should at least provide consistency with other implementations of that feature (i.e. Apple, where tests have shown, that Apple treats dates with the year 1604 as partial dates without a year, even if the property X-APPLE-OMIT-YEAR is missing).


  • developer

    @michaelroland said in BDAY without year for VCARD 3.0 if server drops property X-APPLE-OMIT-YEAR:

    The server, unfortunately, cannot be “improved” in that case. Anyways, I don’t see a need for that since it speaks vCard 3.0 perfectly fine and I can (more or less) live with the featureset of vCard 3.0.

    Why can’t the server be improved so that it understands vCard 4? vCard 4 was published in 2011 and it has been adopted widely. All this discussion here is about working around a problem which has been solved well 8 years ago.

    Hence, in my opinion, DAVx5 shouldn’t have allowed partial dates for vCard 3.0 in the first place, as the implementation of the feature actually introduces a violation of the vCard 3.0 specification (i.e. a bug).

    I understand the argument that vCard 3 BDAYs MUST not have any parameters (which I did not know until now):

       ;For name="BDAY"
       param        = ("VALUE" "=" "date")
            ; Only value parameter allowed
    
       param        =/ ("VALUE" "=" "date-time")
            ; Only value parameter allowed
    

    But since DAVx5 does implement the feature, it should at least provide consistency with other implementations of that feature (i.e. Apple, where tests have shown, that Apple treats dates with the year 1604 as partial dates without a year, even if the property X-APPLE-OMIT-YEAR is missing).

    I see these possibilities (only regarding vCard 3, because in vCard 4, there are no problems):

    1. Restrict Android to not offer partial dates in the contact schema at all, so that users cannot enter partial dates. This is how it has been until users have explicitly requested this feature because it’s available in Android and it’s available in vCard 4. Unfortunately, it’s not possible to (dis)allow partial dates according to server vCard 4 support because this support may change from sync to sync (and even if it wouldn’t, it can’t be set per account in Android).
    2. Allow users to enter partial dates and use Apple’s X-APPLE-OMIT-YEAR parameter¹ without assuming a default value for it (current implementation). Will convert partial dates (which are not supported by vCard 3) to dates in 1604. This makes the following use case inconsistent:
      1. user enters a partial date (which is not guaranteed to be supported by the server) on Android and syncs with DAVx⁵
      2. server removes X-APPLE-OMIT-YEAR, thus converting it to a full date with year 1604
      3. when the vCard is synced back to DAVx⁵, the full date with year 1604 appears (which sounds legitimate to me given that the server doesn’t support partial dates)
    3. Allow users to enter partial dates and use Apple’s X-APPLE-OMIT-YEAR parameter¹ with assuming 1604 as default value. In this case, the following use case will be inconsistent:
      1. user enters a vCard with full date in year 1604 (for instance, birthday of Anna Francisca de Bruyns) and syncs to server
      2. when the vCard is synced back to DAVx⁵, the year is lost and the birthday is cropped to day and month.

    ¹ Of course, another parameter or even property (X-DAVX5-PARTIAL-BDAY …) could be used instead, but because Apple implementations already use X-APPLE-OMIT-YEAR, I think it makes sense to adopt it.

    So, there’s always a case with inconsistent behavior, which is a logical consequence of the fact that vCard 3 doesn’t support partial dates.

    Now: Which case is more important? I agree that there won’t be many vCards with year 1604 in the wild, but on the other side, it would be a real data loss without gaining any functionality (in this use case). You can upload a vCard with BDAY in 1604, then sync again and the birthday would just be gone without any reason!

    In everyday use, most vCard won’t have a BDAY of 1604 and assuming this year as default value will provide good results. Also, it seems to be Apple’s default behavior, as you say. So, the question is, whether we would like to sacrifice conformant behavior for the year 1604 for convenience in all other years. Doing so would hurt my heart 💔, but I guess it would indeed provide best results… I only hope that I won’t ever have to explain to an angry user why DAVx⁵ always drops the year from BDAYs in 1604.


  • developer

    Another thing which I don’t understand: Why even use X-APPLE-OMIT-YEAR if 1604 is assumed in any case? Why not just write partial dates as BDAY:1604-mm-dd (and assume that every date with 1604 is a partial date), wouldn’t it be the same?

    Or does Apple use X-APPLE-OMIT-YEAR=1605 (or another non-1604-year) if the BDAY year is really 1604?



  • Another thing which I don’t understand: Why even use X-APPLE-OMIT-YEAR if 1604 is assumed in any case? Why not just write partial dates as BDAY:1604-mm-dd (and assume that every date with 1604 is a partial date), wouldn’t it be the same?

    Or does Apple use X-APPLE-OMIT-YEAR=1605 (or another non-1604-year) if the BDAY year is really 1604?

    That is indeed a good question. I’ll try to do some tests when I get the next chance to test with an iPhone (I don’t have one myself).

    Why can’t the server be improved so that it understands vCard 4?

    Simply because the server is not under my control. I agree that upgrading the server really is the only way to add new features though.

    1. Restrict Android to not offer partial dates in the contact schema at all, so that users cannot enter partial dates. This is how it has been until users have explicitly requested this feature because it’s available in Android and it’s available in vCard 4. Unfortunately, it’s not possible to (dis)allow partial dates according to server vCard 4 support because this support may change from sync to sync (and even if it wouldn’t, it can’t be set per account in Android).

    I wasn’t aware of that.

    So, there’s always a case with inconsistent behavior, which is a logical consequence of the fact that vCard 3 doesn’t support partial dates.
    Now: Which case is more important?

    To be honest, the arguments for both sides are pretty good and I’m no longer sure which one really is the best choice. (Maybe unless the answer to "
    Or does Apple use X-APPLE-OMIT-YEAR=1605 (or another non-1604-year) if the BDAY year is really 1604?" is yes, since option 3 would probably cause the least loss in that case.)


Log in to reply