Interpretation of negative years in the units attribute

I have encountered an issue with using a negative year in the units attribute of time variables in NetCDF files. The interpretation in cftime (Python) is that year zero does not exist, while in other software such as Panoply the interpretation is that year zero exists. This affects how the time variable is read and displayed, and effectively causes one year difference between the different implementations. The CF Conventions (Section 4.4. Time Coordinate) do not explicitly state how negative years should be treated, except for stating that year 0 has a special meaning. On the contrary, ISO 8601, seems to be more on the side of including year 0.
In particular, this issue comes up when using Julian date in NetCDF files, which has a reference time of 1 January 4713 BCE, 12:00 UTC. As of now it is impossible to use it in NetCDF files and get consistent results in Python (through the netCDF4 package) and Panoply.
I suppose there are multiple possible solutions to the problem. Either all implementations start using the same method of counting
negative years (and it would be helpful if the CF Conventions make this unambiguous), or there would have to be information about the year numbering convention included in the NetCDF file, such as a new attribute or an indicator included in the units or calendar attributes.
Related issue in cftime: #200.

@peterkuma, CF has never standardized the meaning of year zero or negative years.  As you have discovered, different software developers have implemented various and conflicting interpretations.
Best practice is to encode all timekeeping so that zero and negative are never encountered in either recorded times or in the reference time in the units attribute.  Furthermore, when recording modern real world times, use only years later than 1582 in both positions, to avoid the Julian/Gregorian crossover.  Please see CF section Time Coordinate for more details and caveats.
For most applications, I recommend a reference date of January 1, hour zero, of the first year of your data domain, or some other round year number close to but earlier than the start.
It seems like you have an application that is well aware of correct real world dates and times when the data are originally being recorded.  Is there something that would prevent this application from encoding times in this unambiguous way, relative to a modern reference time?

@Dave-Allured, thank you for your response. As you say the issue can be avoided by using a reference time after 1582, which is fine for end users who can choose the reference time. However, I think the situation for the developers of generic software which uses NetCDF is still unresolved, because they don't have a concrete guidance on how to use these reference times. My proposal would be to add text to the CF Conventions saying how negative years should be interpreted, even if it is something as short as:
"When the year of the reference time is negative, year 0 is not counted in calculations involving this reference time."
(or a similar statement), appended to the second paragraph of Section 4.4. Time Coordinate.
To answer your question, I write relatively generic software for use with climate observations and climate modeling, which doesn't know what time range is going to be used by the user. I prefer to use Julian date everywhere in my code because it makes it easy to perform any calculations when all time variables have the same reference time. It would be great if NetCDF had a good support for this use case.

@peterkuma, I share your interest in standardizing the treatment of zero and negative years.  However, I am afraid your use case may not appropriate for this task.  My experience so far is that almost all climate-related obs and model data sets that might use CF encoding are in the domain of only positive year numbers.  I speculate that most climate model makers deliberately avoided zero and negative years because of this uncertainty.  I might be wrong, I have not checked lately.
You are writing generic software for climate obs and modeling.  If you plan to use a fixed reference time for internal software purposes, then I suggest 1 January +0001 00:00, rather than the astronomical calendar base that you mentioned, to reduce problems.
If that is not satisfactory, then I am glad to keep discussing a CF amendment.

@Dave-Allured : I think this does deserve some further discussion because the study of climate in the distant past is a very important part of climate science, even if it is small in scale compared to the study of present day climate. Our problem is that the distant part is more important for our community than it is for many of the people who work on standards for dates and times.
The NetCDF4 library may have resolved this for us, unless we make an active decision to depart from the treatment of negative reference times in NetCDF4. For example, if I create a file from the following CDL using ncgen (from version 4.6 of the NetCDF library):
netcdf time_ex01 {
dimensions:
	time = 3 ;
variables:
	double time(time) ;
		time:standard_name = "time" ;
		time:units = "days since -0001-01-01" ;
		time:calendar = "standard" ;

// global attributes:
	:Conventions = "CF-1.7" ;
data:
time = 0, 365, 731 ;
}

and then run ncdump -t, the resulting time values are given as: time = "-0001-01-01", "0000-01-01", "0001-01-01" ;. i.e. NetCDF4 interprets 0001-01-01 as being two years after -0001-01-01. Unfortunately, this is not well documented in the NetCDF User Guide, but it is unambiguous. I think this takes precedence over the cftime library, because we are trying to build on top of the NetCDF data model ... but there may be other interpretations of that.

This has been discussed in CF before but without conclusion. It would certainly be useful to adopt a convention for it, because there are use-cases, as @peterkuma demonstrates. It's not a problem with the reference year itself, but with the definition of the calendar. Given the lengthy debates about what "calendar" means when we were discussing leap-seconds, I use that word with some nervousness! I mean by "calendar" the set of valid dates (DD-MM-YYYY), which is implied by the choice of the calendar attribute in CF.
In the standard calendar, as we all know, there is no year between 1 AD (CE) and 1 BC (BCE).  I suppose it's because year 0 doesn't exist that COARDS chose year 0 to indicate climatological time. (CF supports that convention for compatibility with COARDS, which only deals with the real-world standard calendar.) I'm interested to see what @martinjuckes reports about NetCDF-4. If you accept 0 as a valid year number, it means you have to write 2 BC as year -1, 3 BC as year -2, etc. That seems rather confusing to me, and likely to lead to mistakes. However, it seems that this is what is done for the proleptic Julian calendar, which is used in astronomy. Wikipedia says, "year 1 of the Julian Period was 4713 BC (−4712)."  It seems that there is a year 0 in that calendar. Is that correct? For model calendars, I guess that year zero probably does exist, because it's an inconvenience to arithmetic if you leave it out!
If we decide there isn't a well-defined best answer, and there are divergent use-cases, we could define different CF calendars with and without year zero.

I'm pretty sure that netCDF-C's support of dates is really just for minimal convenience and not intended to be any kind of standard. I'll poke @WardF and @lesserwhirls to chime in here...

It might be reasonable to define the standard calendar as not permitting years less than 1. Whether or not year 0 exists is a choice for the proleptic calendars, I think.

I initially liked Jonathan's idea of introducing a new proleptic calendar(s) to make it explicit when people care about the interpretation of negative years in the reference time, but, after thinking over the point discussed below, I would prefer to use a qualifier, e.g. proleptic_gregorian cardinal
If you take an etymological approach, I think AD 1 refers, in effect, to "year 1": i.e. it is a reference of a time period, not a point in time. Similarly, 1 BC is "year 1 before".  From that perspective, it is natural that there is no AD 0 or 0 BC. UTC adopts the convention that 2020-01-01 00:00:00 refers to the start of AD 2020, but says nothing about negative times.
The question, I think, is not "Is there a year zero in the calendar?" but rather "How do we encode a given calendar year in the time stamp?".
Given that positive YYYY in the datestamp is universally understood to refer to AD YYYY, arguments can be made for interpreting -YYYY as either and extension backwards treating the years as a sequence of integers, or as 1 BC. This is an encoding choice. For this reason, I would not modify the calendar, but instead add an optional qualifier to identify the convention for encoding BC years in the timestamp.
I'm not sure whether there is a good mnemonic term, but I suggest proleptic_gregorian cardinal to refer to use of cardinals, -1, 0, 1 rather than ordinals, 2nd before, 1st before, 1st after.

netCDF-C support for dates/times/calendars is limited to the ncdump utility, and I believe only as a convenience (nctime0.h isn't installed as part of the library). It has been extended over time to be more flexible with respect to both UDUNITS as well as to better operate with different calendars. I would strongly recommend that its behavior with respect to time be viewed as any other netCDF based client lost in the fog of the various real and imaginary calendars, and not be viewed as a sort of reference implementation (or even guidance) regarding date/time/calendar handling for netCDF files generically.

I really appreciate that others have joined the discussion. From my understanding the ISO 8601 standard should be considered as a mapping to the underlying calendar, i.e. year 0 and -1 in ISO 8601 are mapped to year 1 BCE and 2 BCE, respectively. In that sense, there is no conflict between ISO 8601 and the calendar, even though it is slightly confusing. The ISO 8601 document itself is probably a better source of information than Wikipedia. In section B.1 (Date and time representations) of the ISO 8601:2004 version it has an example:

Basic format
Extended format
Explanation

−00020412
−0002-04-12
Expanded; four digits to represent the year. The twelfth of April in the second year before the year [0000]

Other than that it is relatively short of good explanation about how negative years should be treated. Two other relevant fragments in the document are:

"NOTE In the proleptic Gregorian calendar, the calendar year [0000] is a leap year." (Section 3.2.1 The Gregorian calendar)

"By mutual agreement of the partners in information interchange, it is permitted to expand the component identifying the calendar year, which is otherwise limited to four digits. This enables reference to dates and times in calendar years outside the range supported by complete representations, i.e. before the start of the year [0000] or after the end of the year [9999]." (Section 3.5 Expansion)

The newer version of the ISO standard from 2019 defines extensions in ISO 8601-2:2019:

"In ISO 8601-1, a negative calendar year cannot be expressed for the years -0001 through -9999. This subclause removes that restriction. ... When a negative calendar year represents a date, the negative value is to represent the number of years prior to year zero (0) (year zero is expressed as '0000' in implicit form and '0Y' in explicit form." (Section <IP_ADDRESS> Calendar year)

"The calendar year before year one (1) is represented as follows:
Explicit:
[yearE]["B"]
EXAMPLE 1 '1YB' is the first year before year one (1), equivalent to the effect of '0Y'.
EXAMPLE 2 '12YB' is the twelfth year before year one (1), equivalent to the effect of '-11Y'."
(Section <IP_ADDRESS> Calendar year before year one (1))

Therefore, it looks like both ways of counting/not counting year 0 are supported by the standard, and they are distinguished by adding "YB" to the year number without leading zeros in the "explicit form".
I think it would be desirable to follow ISO 8601 (but I am not sure about the "YB" form because it may be too complicated to parse all variations of the format), unless there are historical reasons not to, such as how the handling of negative years has been implemented in udunits. I will try to do a short survey of how existing NetCDF libraries implement zero and negative years.
I have been in contact with the developer of Panoply (Robert B. Schmunk, @rschmunk - I hope that is his GitHub username), who said that handling of dates in Panoply follows standard Java classes, which is according to the ISO 8601 standard of including year 0 in the calculations.
@Dave-Allured, I wouldn't be trying to only solve my use case here. I know I could work around it easily by choosing a reference time with a positive year. I am quite interested in solving the issue for all users of NetCDF, as much as I can contribute to the discussion. It looks like there is enough interest from others too.

@peterkuma thanks for the detail, I was looking at ISO 8601-2014 (accessed in 2018) ... and the treatment of years -9999 to 0 has clearly be considerably enhanced in the 2019 version, especially in the extension (8601-2). I've just downloaded a new version.
The NetCDF Java library has quite extensive calendar support .. but the only thing I could find in the NUG that our convention references was a link to the CDL functionality which I've illustrated above. I agree completely with @lesserwhirls that the NetCDF libraries, and libraries in general, should not be treated as a standard or convention, but we have to consider the consequences of recommending anything that conflicts with a widely used library.
Using the new explicit  ISO 8601 form for dates may help to make the distinction between the two mappings clearer, with 1YB equivalent to 1 BC and 0000-01-01 as  1 year before 0001-01-01. A complete date and time looks like this: 1985Y4M12DT23H20M30S, which would require some extra parsing code. There is, however, a lot of flexibility in the ISO standard, as you might expect. I have doubts about an approach which would require users to deal with the full range of options.

Thank you, @peterkuma, for the useful information, and to @martinjuckes for his correction to the question - not "Is there a year zero in the calendar?" but rather "How do we encode a given calendar year in the time stamp?". I think these are linked in the CF convention. To be precise, I think we could say that the CF calendar attribute indicates both the set of valid dates in the calendar (YYYY-MM-DD) and the specification for mapping a valid date-time to a unique number (i.e. the encoding of date-time as a time coordinate). Though I appreciate Martin's point that these are two concepts, which is why he prefers a qualifier, since you must have both and there are few possible combinations it feels more robust to me to keep an indivisible attribute for them.
Therefore I suggest that for the default/gregorian/standard calendar, we recommend that the reference date should not be earlier than year 1, and that no date earlier than year 1 should be encoded in this calendar, to avoid the ambiguity. That means the CF-checker would produce a warning (but it's not an error). We shouldn't retrospectively define what negative years mean because we don't know the intention of existing data. I suggest that we define two new calendars:

gregorian_zero, in which year 0 means 1 BC, and any year is allowed in the reference date.

gregorian_nozero, in year -1 means 1 BC, year 0 is not allowed in the reference date and dates in year 0 cannot be encoded. These latter two would give errors.

Any other calendar where the same ambiguity exists could have the same treatment, if there are use-cases which need them. This would be for Julian and proleptic Gregorian calendars, since the other two are model calendars in which I think we can assume year 0 is valid.

Well I see that my feeble attempts to avoid the year zero issue have failed.  I think that the focus in this conversation is good, and I hope we can reach a clear resolution for all six CF defined calendars.  Thanks everyone so far, for your research and attention to detail.
I support the ISO 8601 "expanded representation" approach for the interpretation of year numbering.  ISO 8601 deals not specifically with calendar definitions, but rather with how to construct string representations.  This is relevant for the reference time in the CF units string.  As reported by @peterkuma, this representation puts year numbers on a mathematically normal integer time axis that includes negative years and year zero.
@martinjuckes, I would prefer to stay with the familiar year-month-day string syntax, and avoid the new explicit ISO 8601 form that adds new designators such as "Y" and "YB".  I think it will be sufficient to simply add explicit documentation for the proper CF treatment of negative and zero year numbers in the units string.
I favor adding constraints for two of the CF calendars.  This is a different way of avoiding the year zero issue, specifically an attempt to keep most common applications "safe" from crossover problems.  The calendar named "Gregorian" should be restricted to only dates from 1582 October 15 forward.  This would apply to both the reference date and all encoded dates.  This should be fully compatible with existing data sets that have paid any attention to stated best practices for many years now.  Likewise, the calendar named "Julian" should be restricted to only 0001 January 1 forward.
As a result, the need to clarify negative and zero years would be reduced to only the remaining four CF calendars:  360_day, 365_day, 366_day, and proleptic_gregorian.

Dear @Dave-Allured et al.
We must have had a similar discussion some time ago - it feels familiar! While I appreciate wanting to avoid the Julian-Gregorian transition, I don't think we should disallow the default/standard calendar before 1582. This calendar has always been clearly defined as the mixed Julian/Gregorian calendar; it's the real-world calendar, and we can't exclude a need for real-world time axes which cross the transition.
The Gregorian calendar is undefined before 1582. Possibly we could redefine gregorian in the way Dave suggests (not allowing encoded dates or reference dates before 1582). That would give it a different meaning from default/standard in future data. This change could be a pitfall for interpretating any existing data which says calendar="gregorian" for time coordinates before 1582, but I think gregorian is less likely to have been used than standard or default since it is truly not Gregorian for such times!
However, in view of this point of Dave's, I'd like to change my proposal for new calendar names to:

mixed_withzero, in which year 0 means 1 BC, and any year is allowed.

mixed_nozero, in which year -1 means 1 BC, year 0 is not allowed in the reference date, and dates in year 0 cannot be encoded.

For years>0, both of these calendars are the same as the default/standard calendar. In that calendar, years<1 should be deprecated.
For julian and proleptic_gregorian, years before 1 should be deprecated, and we could define _withzero and _nozero variants correspondingly if they are needed.
For noleap=365_day, all_leap=366_day and 360_day, I think we could assume that year zero and negative years are allowed. The current definitions describe them as "Gregorian" calendars, which isn't really a useful statement! I would redefine them as calendars in which months have the same lengths in every year. In noleap, the month lengths are as for a non-leap year of the Gregorian calendar, in all_leap, they are as for a leap year, and in 360_day all months have 30 days.
Best wishes
Jonathan

Dear @Dave-Allured , @JonathanGregory ,
I agree with Jonathan's point that someone may want to encode real world data from the 16th century (e.g. weather records from 16th century diaries) .. and so we should maintain the existing support for using actual the mixed Julian/Gregorian calendar.
For 365_day I agree that the current definition is confusing -- how about "All years are 365 days with months as in a non-leap year of the Gregorian calendar", and a similar statement for 366_day.
I agree with Dave's recommendation to avoid the new ISO 8601-2 explicit form for dates (YB etc). I think we should spell out what we are prepared to accept. E.g. Would we accept the basic form which has no separators within date and time (e.g. 19850412T101530)?  If the basic form is allowed, it is necessary, to avoid confusion, that a fixed number of digits be used for the years (4 by default, but it can be expanded as long as the length is agreed between parties exchanging data). If we stick to what they call the extended form (e.g. 1985-04-12T10:15:30) the number of digits in the year can be varied without ambiguity.
There is currently a special meaning attached to reference dates of the form 0-1-1, for backward compatibility with COARDS, in section 7.4. Can we remove this feature from CF-1.9?

Dear @martinjuckes and @Dave-Allured

For 365_day I agree that the current definition is confusing -- how about "All years are 365 days with months as in a non-leap year of the Gregorian calendar", and a similar statement for 366_day.

Yes. I agree.

I agree with Dave's recommendation to avoid the new ISO 8601-2 explicit form for dates (YB etc).

I do too.

I think we should spell out what we are prepared to accept.

Yes. Since CF generally supports udunits formats for units, we ought at least to allow what udunits does for time, but I haven't found out in the units documentation what formats it accepts. I think it will allow Y[-M[-D [h[:m[:s]]]]], where Y can be a large positive or negative number or zero. (NB udunits itself only handles the real-world calendar, but we use its format for the others.)
I agree with @Dave-Allured that it's OK to continue to allow but deprecate the special use of year 0 in the real-world calendar.

if we can get consensus that dates earlier than year 1 are not valid in the existing standard (or default) and julian calendars under CF ...

I think that years<1 should be deprecated in these calendars, but not disallowed, because of backward compatibility. What do @martinjuckes and others think?
Above (https://github.com/cf-convention/cf-conventions/issues/298#issuecomment-698987558) I have made proposals for new calendars, going before year 1, and asked whether gregorian should be redefined.
Jonathan

agree with @JonathanGregory   on deprecating (rather than disallowing) years < 1 in standard and julian calendars (where I interpret this to refer to the year in the reference time stamp).
I'm not sure about the proposal to redefine gregorian : it is currently defined as mixed Gregorian/Julian which appears OK. I don't have a clear opinion on this.
Concerning what udunits2 supports: the command line tool treats 0-0-0 as equivalent to 1-1-1  and  -1-1-1 as being  366 days apart. udunits2 uses a mixed Gregorian/Julian calendar.
The library does accept arbitrary years and ISO basic format. This means that 19850101 is equivalent to 1985 or 1985-01-01. This means that the -MM is not optional when you want to reference years with more than 4 digits. It looks like a rather fragile approach to me, and documentation is lacking. Does anyone know of people wanting to use the ISO basic format, with no delimiters in the date? Could we simplify the specification (and parsing requirements) by insisting on the ISO "extended format", which has - as a delimiter in the date and : in the time?

Dear @martinjuckes

agree with @JonathanGregory on deprecating (rather than disallowing) years < 1 in standard and julian calendars (where I interpret this to refer to the year in the reference time stamp).

Yes, it would apply to the year in the reference timestamp, and I think it would also mean deprecating any attempt to decode or encode a time before year 1. The CF checker would be able to detect such years in the time coordinate, and should give a warning about it, because their meaning would be unreliable.

I'm not sure about the proposal to redefine gregorian : it is currently defined as mixed Gregorian/Julian which appears OK. I don't have a clear opinion on this.

My suggestion would be to make gregorian different from standard and default, by deprecating times before the change of calendar in 1582 for gregorian (rather than year 1 for the others). If you say it's Gregorian (rather than mixed or proleptic_gregorian), it really should not exist before that calendar was introduced!

Could we simplify the specification (and parsing requirements) by insisting on the ISO "extended format", which has - as a delimiter in the date and : in the time?

Alternatively we could define what it means if you supply a date consisting of more than eight digits and no delimiters. But that would imply a requirement on software to support our interpretation. Maybe we could deprecate it instead of disallowing it.
Jonathan

My suggestion would be to make gregorian different from standard and default, by deprecating times before the change of calendar in 1582 for gregorian (rather than year 1 for the others). If you say it's Gregorian (rather than mixed or proleptic_gregorian), it really should not exist before that calendar was introduced!

:+1: for this, and in particular for the last sentence.

I think it would help to confine this discussion to the requested issue, which is zero and negative years in currently defined calendars.  A refinement of the "Gregorian" label is a good topic, but I should not have injected it into this discussion.
Also a full discussion of alternate date formats in the reference string is complicated.  Can we please defer that to a future issue, when needed?
I wholeheartedly support new calendar names that are explicit and mathematically well-defined.  It is relevant to mention those ideas here.  However, can we also put off their resolution to new issues, as needed?
Let's see if we have some consensus so far on the following, acknowledging some previous agreement above.

For the reference date in the units string, continue to assume that the year number is easily recognizable and parseable.  (There are currently no CF explicit format rules.  We assume something like the UDUNITS delimited format shown in section 4.4 Time Coordinate.

Rules will be added to explicitly allow zero and negative year numbers in the reference date.  A negative year number will be indicated by a preceding minus sign, with no other adornment.

To handle all possible cases, the interpretation of zero and negative year numbers will be explicitly defined for each defined CF calendar type.

For the current standard  and julian calendars (and synonyms), zero and negative years will be deprecated for multiple reasons.

For the current 360_day, 365_day, and 366-day calendars (and synonyms), year numbering will be the complete set of integers, including zero and negative.

Proleptic_gregorian is problematical.  Let's talk about that more later.
Agreed so far?

Dear @Dave-Allured
Thanks for the summary. Yes, I agree with all those bullet points. I would like to add

In calendars where negative and zero years are deprecated in the reference date, it is also deprecated to record dates in those years in the variable (even by using a reference date with a positive year).

Jonathan

@JonathanGregory,  I agree with your addition.  That was my intention, I just did not fold that into the wording correctly.

I have not much to add to this discussion, my earlier comment was only to express my support the suggestion to make the calendar names/terms clearer and more self-evident.
For what it is worth, @Dave-Allured's summary and @JonathanGregory's addition looks good to me.

I am coming around to favoring a partial ISO 8601-2:2019 approach as described above by @peterkuma.  Both ways of either counting or not counting year 0 could be supported with some minimal extension of the reference date notation, as initially suggested above by @martinjuckes.  I have a suggested notation that I would like hold for later.
Let's continue to focus on the primary question of year numbers in the traditional CF format, without any new notation.  By ISO 8601-2:2019, and if we agree, year zero and negative years are included.
Now the interpretation for proleptic_gregorian is still undecided.  I suggest that the current, unadorned proleptic_gregorian should include year zero and negative years for general scientific usage.  I do not know of any data sets that have encoded zero or negative years in a conflicting way with proleptic_gregorian.  Also there is precedent for this outside of CF; see the Wikipedia article.
@JonathanGregory, you proposed that years before 1 should be deprecated for proleptic_gregorian.  Do you have a specific reason for preferring this?

Hello @Dave-Allured

I agree on sticking to the format illustrated in  section 4.4 Time Coordinate -- in ISO terminology this means accepting the extended format (which has year, month and day separated by "-") and excluding the ISO "basic format", which has a more compact string.

I also agree on the suggested approach to supporting zero and negative reference years with explicit specifications, and deprecating them in some cases.
Also tend to favour allowing negative years in the proleptic_gregorian, as it appears to be designed for continuity going backwards in time.

you proposed that years before 1 should be deprecated for proleptic_gregorian. Do you have a specific reason for preferring this?

Only the supposition that it might be not well-defined what year zero means. If the consensus is that year 0 is a normal year in the proleptic Gregorian calendar, I think that's good. We can allow zero and negative years for this calendar.
The withzero and nozero options are most relevant for the Julian and standard calendar, I suppose.

I believe that ISO8601 is as good a definition as we have for the datetime stamp, the Gregorian calendar, and the Proleptic Gregorian calendar.
ISO8601 is explicit in the inclusion of year 0000 and its interpretation.

years prior to 1583 are not automatically allowed by the standard. Instead "values in the range [0000] through [1582] shall only be used by mutual agreement of the partners in information interchange."

CF is a good example of mutual agreement between partners.
An expanded year representation [±YYYYY] is available, again by mutual agreement. and it must be prefixed with a + or − sign.
By convention 1 BC is labelled +0000, 2 BC is labeled −0001.

@marqh, I am proposing only one idea from ISO8601, the mapping of zero and negative year numbers as you just showed.  Year 0 = 1 BC, etc.  I am not proposing a full adoption of an ISO8601 format.  ISO8601 uses fixed length numbers, whereas the CF date/time stamp allows variable length numbers with delimiters.  Also, CF does not use the plus sign.
The delimited system is robust and has served us well for a long time.  The CF delimited system accommodates ISO8601 fixed width formats when the standard delimiters including the "T" separator are used.  E.g., YYYY-MM-DDTHH:MM:SS is correct under both systems.

The UDUNITS-2 library could be modified to interpret the timestamp in a
time "unit" using the proleptic Gregorian calendar rather than the
currently-used hybrid Julian/Gregorian calendar.
The question is whether or not this would be a good idea.
Regards,
Steve Emmerson
UDUNITS Developer
On Tue, Oct 27, 2020 at 2:15 PM Dave Allured<EMAIL_ADDRESS>wrote:

@marqh https://github.com/marqh, I am proposing only one idea from
ISO8601, the mapping of zero and negative year numbers as you just showed.
Year 0 = 1 BC, etc. I am not proposing a full adoption of an ISO8601
format. ISO8601 uses fixed length numbers, whereas the CF date/time stamp
allows variable length numbers with delimiters. Also, CF does not use the plus
sign.
The delimited system is robust and has served us well for a long time. The
CF delimited system accommodates ISO8601 fixed width formats when the
standard delimiters including the "T" separator are used. E.g.,
YYYY-MM-DDTHH:MM:SS is correct under both systems.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/cf-convention/cf-conventions/issues/298#issuecomment-717512280,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAEVZ7P4VERDGTWK4QUSNDLSM4S5LANCNFSM4ROMDBIQ
.

Sorry for the delay.  Here is a new and simplified proposal for zero and negative year numbers in time coordinates.  I think this represents a consensus of the current discussion.  I avoided several side issues that were discussed, but are not directly relevant.

For the current standard and julian calendars (and synonyms), zero and negative years are prohibited.

For the current 360_day, 365_day, 366-day, and proleptic_gregorian calendars (and synonyms), year numbering is the complete set of integers, including zero and negative.

See pull request #315 for the actual changes.  I also added this minor wording change to clarify the exact meaning in some places.

Change  "date string" and "time string", where appropriate, to "reference date/time string".

The UDUNITS-2 library could be modified to interpret the timestamp in a time "unit" using the proleptic Gregorian calendar rather than the currently-used hybrid Julian/Gregorian calendar.
The question is whether or not this would be a good idea.

@semmerson, the default behavior of UDUNITS 1 and 2 should stay the way it is.  I am afraid that use of reference dates earlier than the crossover, contrary to two decades of warnings, has been widespread.  UDUNITS is used for time conversion in large amounts of user code and software tools.

The cftime python module currently does not allow year zero for Julian, mixed or proleptic_gregorian calendars, but does allow negative years (back to year Jan 1 year -4713 for Julian and mixed, and Nov 24 year -4714 for proleptic_gregorian).   If this proposal is adopted, this would need to change.

Regarding the use of year zero in the proleptic_gregorian calendar, I understand now why @Dave-Allured proposed allowing this.  One of the few places proleptic_gregorian is used is in ISO-8601 which specifies that year 0 is 1 BC.

@jswhit, sorry for the delay in responding.

What is the rationale for allowing year zero in proleptic_gregorian, but not in the Julian and mixed calendars? It seems more consistent to me to disallow year zero for all 'real-world' calendars.

That is a fair question with a complicated answer.  Here are the main arguments from my viewpoint.

Proleptic Gregorian is not a real-world calendar before the crossover year of 1582.  It is an artificial calendar invented for mathematical convenience, for limited technical applications.

There is a strong need in science and technology for a mathematically simple calendar that goes backward indefinitely.  In contrast, the real-world Julian and Gregorian calendars (not their current CF definitions) are constrained to only dates forward from a starting point or era in history.  This desire for a systematic calendar extending backward puts Proleptic Gregorian into its own category.

I agree with @Dave-Allured's arguments about proleptic Gregorian versus standard and Julian calendars. If there is a use-case for the Julian calendar before year 1, which is disallowed by the present proposal, we can introduce another calendar for it in a later proposal. Jonathan

I need to further address backward incompatibility for the current proposal to include year zero in the unadorned label proleptic_gregorian.  It has already been said that there are conflicting interpretations between several software packages.  @jswhit mentioned this above regarding the cftime python module.  There is further concern in cftime issue #233.  Cftime is not the only library that uses no-year-zero encoding.
My opinion is that this particular problem is limited and manageable, we should proceed to define proleptic_gregorian to include year zero for CF purposes, and this will result in a simpler future.  Here are some supporting arguments.

The status quo with dual interpretations is not tolerable going forward.  CF needs to choose to include or exclude year zero, or else to prohibit year zero and negative years altogether from the unadorned label proleptic_gregorian.

CF is limited to the contents of netCDF files only.  Behavior of external software is out of our control.  We can only hope that external software will not label certain behavior as CF before standard behavior is actually adopted by CF.

Problematic cases are rare, or so I speculate.   The use of proleptic_gregorian excluding year zero is limited to only cases that used negative year numbers in time values, or in the units string.  Furthermore, such cases must have used one of the software libraries using the no-year-zero interpretation.  Most CF applications deal only with observations, forecasts, and modeling in modern times.  Therefore my guess is that use of negative years, and therefore backward incompatible cases, are rare.  If anyone knows of such incompatible cases, it would be worth mentioning here.

There have been sentinels.  I would expect that persons using incompatible negative years in proleptic_gregorian would at some point have run their files through programs such as ncdump and Panoply, and noticed the one-year discrepancy.  This should serve to have reduced the extent of cases using this encoding.

The embedded CF version number less than 1.9, in combination with the proleptic_gregorian attribute value, can help to identify suspicious cases.

Incompatible cases can be remedied.  When an incompatible data set is discovered, either the time coordinates can be rebased to include year zero, or else we can consider adding a new calendar label like proleptic_gregorian_nozero, similar to earlier suggestions by @JonathanGregory.

@JonathanGregory said:

Re the question from @jswhit, I too asked about year zero in the proleptic Gregorian calendar earlier. You said that year zero is conventionally allowed in that calendar. I'm happy to take your word for that.

Careful, I don't think I actually said that.  All that I said was "there is precedent for [including year zero] outside of CF; see the Wikipedia article."  If there was a universal governing standard for Proleptic Gregorian, this conversation would be easier.  I have found no such standard.  ISO-8601 certainly does not count; they are a latecomer to the Proleptic Gregorian party.  Unidata/netCDF has declined authority.
My sense is that there is a slow convergence within scientific and technical communities, on including year zero in the calendar called Proleptic Gregorian, for record keeping purposes.  Astronomical year numbering is the most long standing example.  My opinion is that CF should join this trend.

Dear @Dave-Allured
Thanks for your arguments. I agree we need to make a clear choice, and I'm happy with our following or setting a trend to define proleptic_gregorian (with no qualification) as including year zero.
At https://github.com/cf-convention/cf-conventions/issues/298#issuecomment-794196013 I made some other comments on your proposed text.
Best wishes
Jonathan

@JonathanGregory , thanks for working on the details.  Sorry about this late reply.  Referring again to PR #315:

... After the deprecation of year zero in reference date/time, I'd like to add the following for the avoidance of doubt. Alternatively it could be inserted after "prohibited for certain calendars, as noted below."

Date/times in zero or negative years are prohibited by calendars which prohibit these years in the reference date/time. In these calendars, it is an error to store or decode a time coordinate value for a date/time earlier than 1-1-1 0:0:0, regardless of the reference date/time in the time units.

This seems to be fully redundant with my current wording.  In each of the appropriate calendar descriptions, I already have:

Date/times earlier than 1-1-1 0:0:0 are prohibited.

Then at the bottom, I have:

Some calendars have a restricted time range, as noted, to avoid multiple interpretations. These restrictions apply to both the reference date/time string, and to encoded time values.

Perhaps you missed this bottom part?  Should this be repositioned to make it easier to see?  Note also that I am making some effort to keep the wording reasonably concise, and to avoid unnecessary repetition.

I also agree with your deprecation of the year 0 climatological convention, but it is stronger than what section 7.4 currently says, which is, "We do not recommend this convention." That sounds the same, but it's not currently noted in the conformance document for section 7.4. Therefore I think we must either not deprecate it in 4.4, or deprecate it in 7.4, to be consistent.

Agreed.  I reverted to "not recommended".  Please see new wording in #315.  Your further suggestions are welcome.

Another small suggestion: I think date-time with a hyphen would be better than date/time with a slash. I understand "/" to indicate alternatives, whereas "-" joins words.

Date/time with slash is consistent with long-standing current usage, also with related external usage.  This is a minor style issue.  Either spelling would be reasonable.  Guidance for forming these kinds of compounds is nuanced.  Please move this to a new issue if you want to pursue it.  Thank you.

Dear @Dave-Allured
You're right, I didn't notice this statement further down:

Some calendars have a restricted time range, as noted, to avoid multiple interpretations. These restrictions apply to both the reference date/time string, and to encoded time values.
Perhaps you missed this bottom part? Should this be repositioned to make it easier to see? Note also that I am making some effort to keep the wording reasonably concise, and to avoid unnecessary repetition.

Yes, I do think it would be better further up, at the end of the year-zero paragraph, so all the general points are made together. Since it applies to any restriction on dates, not just year zero but also e.g. there is no 31st of any month in the 360-day calendar, I suggest stating it more generally - and concisely:

Dates which are not permitted in the calendar of the time coordinate variable cannot be encoded as time coordinate values and must not be used in the reference date/time string.

There is one occurrence of "date/time" in the present version of the standard and none of "date-time" so I won't dispute it! I will note that https://github.com/cf-convention/cf-conventions/pull/316 should be amended.
I note that "preceding" has a typo.
Please add yourself to the list of authors.
Best wishes and thanks
Jonathan

@Dave-Allured, thank you for those changes. I agree with all that. In the conformance document, I think we also need

The reference date/time in the units must be a legal date/time in the specified calendar.

which could be a separate statement from, or possibly combined with, your statement

Encoded time coordinates must be legal date/time values in the specified calendar.

Jonathan

The reference date/time in the units must be a legal date/time in the specified calendar.

Hmmm.  This line is already present in CF 1.8 conformance.  But it is under section 4.4, not  4.4.1.  It looks like the previous authors wanted to address the units attribute in 4.4, and the calendar attribute in 4.4.1.  However, this does seem a little odd, splitting up related content restrictions like this.  What do you suggest?

Thanks, well-spotted. That division doesn't seem useful to me either. I would be happy with deleting the 4.4.1 subsection break in both the standards document and the conformance document.

Hmmm.  I can't agree with deleting the subsection break.  There is too much history behind it, and it makes a lot of sense the way it is.  This style is widely used elsewhere in the conformance document.
I think we should either move sentences, or leave this exactly the way it is now with my current additions.  I mildly favor the latter.  Your thoughts?

One more thing.  I want to work this line in somewhere, but I can't figure out where to put it.  Your thoughts?

Do not publish any serious works on April 1.

One more thing. I want to work this line in somewhere, but I can't figure out where to put it. Your thoughts?

Do not publish any serious works on April 1.

We could perhaps define a nofool calendar, in which 1st April is not a permitted date.

Dear @Dave-Allured

Hmmm. I can't agree with deleting the subsection break. There is too much history behind it, and it makes a lot of sense the way it is. This style is widely used elsewhere in the conformance document.

The conformance document follows the standard document in sections and subsections. When someone wonders which section to put something in, because the distinction doesn't seem clear, I think it's reasonable to infer that the distinction is actually unnecessary, and we can save thought and possible confusion by abolishing it. Introducing divisions is good for efficiency when the amount of stuff is too hard to navigate without them, but if they're not essential I'd rather not have them, because they make things harder. That's the reason for my response! I'm always uncomfortable when a section has a single subsection. I don't see the point in that. I know there are other instances in the standards document and I don't like them but we have more serious matters to attend to than this mild discomfort! :-)

I think we should either move sentences, or leave this exactly the way it is now with my current additions. I mildly favor the latter. Your thoughts?

If you prefer not to muddy the waters by removing the division, I'd leave it where it is and we will live with unclear rationale.
Best wishes
Jonathan

All right, leave the section break as is.  Aside from trepidation about today's date, I think this PR #315 is ready to roll.  Until the next brilliant insight comes along!

It would be helpful if others who commented earlier could please have a look at this version and give their opinion e.g. @larsbarring @martinjuckes @peterkuma. Please note that this issue has the limited intent of clarifying when negative years are allowed. It doesn't aim to deal with all outstanding issues concerning calendars. Thanks. Jonathan

I am in favor of the intent of the changes.  With respect to the wording, I offer two general suggestions:

I think in reference to dates and calendars, we should avoid the terms "real-world", and, rather, say exactly what we mean by it.
I think the references to and description of the possible use of year 0 to represent climatological time are very confusing and need to be rewritten.

Specifically, I suggest:
Replace the paragraph,
The year number in the reference date/time may be zero or negative, except where prohibited
for certain calendars, as noted below.  A negative year number is indicated with a preceding
minus sign.  When year zero is allowed, year numbering is algebraic; i.e., year zero is included
in the counting.  The interpretation for historical year numbering is consistent with
link:$$https://en.wikipedia.org/wiki/ISO_8601$$[ISO 8601] (modern revisions);
by convention, year zero = 1 BC, year -1 = 2 BC, and so on.

with
The year number in the reference date/time may be zero or negative, except in the case of a ``julian``
 calendar or a mixed Gregorian/Julian calendar (denoted by either ``standard`` or ``gregorian``).
When allowed, a negative year number is indicated with a preceding minus sign, and year numbering
includes year 0 (in contrast with the Anno Domini (AD) system of numbering years commonly used by
 western historical scholars in which there is no year 0).  The inclusion of year zero in some CF
calendars _is_ consistent with astronomical year numbering and with
link:$$https://en.wikipedia.org/wiki/ISO_8601$$[ISO 8601] (modern revisions), which stipulate that
year zero = 1 BC, year -1 = 2 BC, and so on.

Also replace the paragraph,
There is a special meaning for year zero in the real-world calendar, that is not recommended for
current work.  See <<climatological-statistics>>.  This is an exception to the prohibition of year
zero for certain calendars.

with
The one exception to the prohibition of year zero for certain calendars is in the now deprecated
special use of year zero to indicate a climatology (see <<climatological-statistics>>).

In the conformance document, isn't the second sentence of the following wrong?
The use of a reference date/time in the year 0 to indicate climatological
time is deprecated. This restriction only applies to the real-world
calendar as used by the udunits package.

This might be interpreted as meaning that use of year 0 for climatology is o.k. for non-real-world calendars, but isn't such use absolutely restricted for any calendar that includes year 0 as a possible real year (like, for example, the proleptic_gregorian calendar)?  If so, the above paragraph needs to be reworded.
This might not belong in this ticket, but in the climatological-statistics section, I would replace the paragraph
The COARDS standard offers limited support for climatological time. For compatibility with COARDS,
time coordinates should also be recognised as climatological if they have a units attribute of
time-units relative to midnight on 1 January in year 0 i.e. since 0-1-1 in udunits syntax, and provided
they refer to the real-world calendar. We do not recommend this convention because (a) it does not
provide any information about the intervals used to compute the climatology, and (b) there is no
standard for how dates since year 1 will be encoded with units having a reference time in year 0,
since this year does not exist; consequently there may be inconsistencies among software
packages in the interpretation of the time coordinates. Year 0 may be a valid year in
non-real-world calendars, and therefore cannot be used to signal climatological time in such cases.

with
For compatibility with the COARDS standard, a climatological time coordinate may (for certain
calendars) be indicated by setting the time coordinate's units attribute to midnight on 1 January in
year 0 (i.e., since 0-1-1), although this is no longer recommended.  Use of year 0 for this purpose
is absolutely forbidden in the case of a calendar where year 0 is a valid year (i.e., for all calendars
except a ``julian`` or a Gregorian/Julian calendar). The reasons for generally avoiding the special
use of year 0 to indicate a climatology are: a) it does not provide any information about the intervals
used to compute the climatology, and b) there may be inconsistencies among software packages
in the interpretation of the time coordinates with a reference time of year 0.

I fully support this, it is a good step towards clarifying the meaning -- and use -- of different calendars, in particular together with what is discussed in #319 . And I support the changes suggested by Karl, with the addition that the use of "gregorian" should be coordinated with #319. If the last of the suggested changes (the one for the climatological-statistics section) is deemed out-of-scope for this issue, I think that it deserves its own focussed issue.

Here are my (minor) comments on the PR #315, based on my limited understanding of the existing CF implementations:

Linking to Wikipedia (ISO_8601) is perhaps unwise, because we don't know how the article is going to change in the future, and the standard should be as standalone as possible (Wikipedia is not intended to be an authoritative resource on any topic). It would be better to link to either a specific version of the article, or link to the ISO 8601 standard instead.
"BC" should perhaps be "BCE", which as I understand is the preferred term in science. I have found one occurrence of the term "BCE" in the current CF Conventions in Section 4.4.1, as part of a quote from the udunits(3) man page, and no occurrence of "BC".
I think it would be good to define a "proleptic_julian" calendar in which date/times earlier than 1-1-1 0:0:0 years are allowed, in analogy with the "proleptic_gregorian" calendar.

I support Karl's proposal. This is a great improvement, and resolves some serious issues of ambiguity.
However, I suggest expanding the calendar definitions slightly in section 4.1 and minimise the discussion of different calendars in the introduction of chapter 4.  In Karl's text there are, I think, too many conditional statements which could cause confusion. Placing the rules for each calendar in the relevant part of section 4.1 could simply the text.
In section 4.1:
julian:
-- Julian calendar. Date/times earlier than 1-1-1 0:0:0 are prohibited. Year 1 corresponds to AD 1 in the Julian calendar.
gregorian or standard
-- Mixed Gregorian/Julian calendar as defined by Udunits. This is the default. Date/times earlier than 1-1-1 0:0:0 are prohibited. Year 1 corresponds to AD 1 in the Gregorian calendar.
proleptic_gregorian.
-- A Gregorian calendar extended to dates before 1582-10-15. That is, a year is a leap year if either (i) it is divisible by 4 but not by 100 or (ii) it is divisible by 400. Year 1 corresponds to AD 1 and year 0 corresponds to 1BC in the proleptic Gregorian calendar.
In the introduction, replace:
The year number in the reference date/time may be zero or negative, except in the case of a ``julian``
 calendar or a mixed Gregorian/Julian calendar (denoted by either ``standard`` or ``gregorian``).
When allowed, a negative year number is indicated with a preceding minus sign, and year numbering
includes year 0 (in contrast with the Anno Domini (AD) system of numbering years commonly used by
 western historical scholars in which there is no year 0).  The inclusion of year zero in some CF
calendars _is_ consistent with astronomical year numbering and with
link:$$https://en.wikipedia.org/wiki/ISO_8601$$[ISO 8601] (modern revisions), which stipulate that
year zero = 1 BC, year -1 = 2 BC, and so on.

with:
The year number in the reference date/time may be zero or negative, except in the case of
a `julian` or `standard`/`gregorian` calendars (see Section 4.1 below for more details).

Note:

inclusion of year zero is clearly stated in this first sentence, so it doesn't need to be repeated.
The connection to AD/BC is easier to discuss in the context of the calendars for which it is relevant.
The wikipedia article on ISO 8601 is useful, but using it as a link in the context of the AD/BC question is misleading: ISO 8601 does not mention AD/BC .. it just states that years should be numbered sequentially, with 0 preceding 1. If a reference for AD/BC is needed, there is a good discussion in  Christian chronology  in the Encyclopedia Britannica and elsewhere, but I'm not sure that we need to discuss it in the Conventions document. The AD/BC system appears to predate the introduction of zero into common usage by the Christian record keepers. Placing references to AD and BC in the relevant calendar definitions makes their meaning clear.

I like Martin's restructuring of the information.  Two further suggestions:
In section 4.1 the no_leap or 365_day calendar is defined as a "Gregorian calendar without leap years, i.e., all years are 365 days long."  I don't think we want to exclude 0 or negative years for this calendar, so we should drop the reference to "Gregorian calendar" and simply define it as "A calendar in which all years are 365 days long."
A similar edit of the all_leap or 366_day calendar is also needed.
Finally, I support  @peterkuma's suggestion to replace "BC" with "BCE"  since this is a more neutral term and is consistent with usage elsewhere.

Yes, I agree, Martin's wording is good -- it is clear and succinct. A couple of minor comments:

The explanation of the  gregorian or standard calendar should state that "Year 1 corresponds to AD 1 in the Julian calendar."
The last sentence of the explanation of the proleptic_gregorian calendar  would become clearer if written "In the proleptic Gregorian calendar year 1 corresponds to AD 1 and year 0 corresponds to 1BC/BCE.

Dear @davidhassell et al.
I will produce some text synthesising the comments made since the current pull request was written.
Since then, the preamble on calendars has been modified as a result of the agreement of issue 313 on leap seconds. As a result, I suggest that the new sentence from the pull request of this issue should go in a different place. Below I reproduce the new text from the working draft, because I think it's useful in spelling out what "calendar" means in CF. I have inserted the extra sentence in bold where I'd suggest putting it.
Cheers
Jonathan
4.4.1 Calendar
A date/time is the set of numbers which together identify an instant of time, namely its year, month, day, hour, minute and second, where the second may have a fraction but the others are all integer. A time coordinate value represents a date/time. In order to calculate a time coordinate value from a date/time, or the reverse, one must know the units attribute of the time coordinate variable (containing the time unit of the coordinate values and the reference date/time) and the calendar. The choice of calendar defines the set of dates (year-month-day combinations) which are permitted, and therefore it specifies the number of days between the times of 0:0:0 (midnight) on any two dates. Date/times which are not permitted in a given calendar are prohibited in both the encoded time coordinate values, and in the reference date/time string.
When a time coordinate value is calculated from a date/time, or the reverse, it is assumed that the coordinate value increases by exactly 60 seconds from the start of any minute (identified by year, month, day, hour, minute, all being integers) to the start of the next minute, with no leap seconds, in all CF calendars. This assumption has various consequences when real-world date/times from calendars which do contain leap seconds (such as UTC) are stored in time coordinate variables:

Any date/times between the end of the 60th second of the last minute of one hour and the start of the first second of the next hour cannot be represented by time coordinates e.g. 2016-12-31 23:59:60.5 cannot be represented.

A time coordinate value must not be interpreted as representing a date/time in the excluded range. For instance, 60 seconds after 23:59 means 00:00 on the next day.

A date/time in the excluded range must not be used as a reference date/time e.g. seconds since 2016-12-31 23:59:60 is not a permitted value for units.

It is important to realise that a time coordinate value does not necessarily exactly equal the actual length of the interval of time between the reference date/time and the date/time it represents.

It is recommended that the calendar be specified by the calendar attribute of the time coordinate variable. The values currently defined for calendar are:
[... to be continued]

Dear all
I have drafted a new version of the affected parts of the text of Sect 4.4, taking account of the comments made since the pull request was revised, mostly as suggested but not quite, as follows:

I included the deprecation of gregorian from issue 319.

I suggest we insert the paragraph with rules about years before 1 just before the list of calendars, rather than the earlier place where it appears in the PR. That follows Martin's point that it's easier to deal with the detail in one place. If we put it here, I don't think we need to insert the prohibitions into the definitions of individual calendars.

I don't think we need to talk about year 0 = 1 BCE etc. because we don't allow years before 1 in the standard and julian calendars (except for climatology). I don't believe it is correct to say that year 0 in proleptic_gregorian is 1 BCE, because that calendar doesn't have the right year lengths. It is not a "real-world" calendar.

As Karl suggested, I avoided using Gregorian to describe other calendars, because they're not.

I stated the Julian rule for leap years, and that we use Gregorian month lengths in all calendars except 360_day and none.

I included Karl's text for the cell methods section, with small changes (in bold) from his version. I say that it is impossible, rather than forbidden, for the year-0 convention to be used for climatological time in calendars where it's a valid year.

I think the reference to udunits.dat is out-of-date, isn't it? What should it be changed to?
Best wishes
Jonathan
4.4 Time coordinate
Variables representing time must always explicitly include the units attribute; there is no default value. The units attribute takes a string value formatted as per the recommendations in the Udunits package UDUNITS. The following excerpt from the Udunits documentation explains the time unit encoding by example:

The specification seconds since 1992-10-8 15:15:42.5 -6:00 indicates second since October 8th, 1992  at  3  hours,  15 minutes  and  42.5 seconds in the afternoon in the time zone which is six hours to the west of Coordinated Universal Time (i.e.  Mountain Daylight Time).  The time zone specification can also be written without a colon using one or two digits (indicating hours) or three or four digits (indicating hours and minutes).

The acceptable units for time are listed in the udunits.dat file. The most commonly used of these strings (and their abbreviations) includes day (d), hour (hr, h), minute (min) and second (sec, s). Plural forms are also acceptable. The reference date/time string (appearing after the identifier since) may include date alone; date and time; or date, time, and time zone. The reference date/time string is required.
...
4.4.1 Calendar
A date/time is the set of numbers which together identify an instant of time, namely its year, month, day, hour, minute and second, where the second may have a fraction but the others are all integer. A time coordinate value represents a date/time. In order to calculate a time coordinate value from a date/time, or the reverse, one must know the units attribute of the time coordinate variable (containing the time unit of the coordinate values and the reference date/time) and the calendar. The choice of calendar defines the set of dates (year-month-day combinations) which are permitted, and therefore it specifies the number of days between the times of 0:0:0 (midnight) on any two dates. Date/times which are not permitted in a given calendar are prohibited in both the encoded time coordinate values, and in the reference date/time string.  It is recommended that the calendar be specified by the calendar attribute of the time coordinate variable.
...
The values currently defined for calendar are listed below. In all calendars except 360_day and none, the lengths of the months are the same as in the Gregorian calendar for leap years and non-leap years.  In the julian and the default standard mixed Gregorian/Julian calendar, dates in years before year 0 (i.e. before 0-1-1 0:0:0) are not allowed, and the year in the reference date/time of the units must not be negative. In these calendars, year zero has a special use to indicate a climatology (see [climatological-statistics]), but this use of year zero is deprecated. In other calendars, years before year 1 are allowed.
standard: Mixed Gregorian/Julian calendar as defined by Udunits. This is the default. A deprecated alternative name for this calendar is gregorian. Year 1 in this calendar is year 1 AD or CE of the Julian calendar.
proleptic_gregorian: A calendar with the Gregorian rules for leap-years extended to dates before 1582-10-15. That is, a year is a leap year if either (i) it is divisible by 4 but not by 100 or (ii) it is divisible by 400.
julian: Julian calendar, in which a year is a leap year if it is divisible by 4, even if it is also divisible by 100.
noleap or 365_day: A calendar with no leap years, i.e. all years are 365 days long.
all_leap or 366_day: A calendar in which every year is a leap year, i.e. all years are 366 days long.
360_day: A calendar in which all years are 360 days and divided into 30-day months.
none: No calendar.
The calendar attribute may be set to none in climate experiments that simulate a fixed time of year. The time of year is indicated by the date in the reference date/time of the units attribute. The time coordinates that might apply in a perpetual July experiment are given in the following example.
...
Replace the paragraph in 7.4 beginning "The COARDS standard" with
For compatibility with the COARDS standard, a climatological time coordinate in the default standard and julian calendars may be indicated by setting the time coordinate's units attribute to midnight on 1 January in year 0 (i.e., since 0-1-1).  This convention is deprecated because it does not provide any information about the intervals used to compute the climatology, and there may be inconsistencies among software packages in the interpretation of the time coordinates with a reference time of year 0.  Use of year 0 for this purpose is impossible in all other calendars, because year 0 is a valid year.
Modify conformance document section 4.4 recommendations:

The use of time coordinates in year 0 and reference date/times in year 0 to indicate climatological time is deprecated.

Add to conformance document section 4.4.1 recommendations:

A time coordinate variable should have a calendar attribute.

The value standard should be used instead of gregorian in the calendar attribute.

Thank you, Jonathan. Your text is very clear to me.
All of the changes required for #319 are now here - is it OK for #319 to just refer to the PR for this issue, rather removing these changes from this issue and recreating in a bespoke PR for #319?

Dear @davidhassell
Yes, you're right, this does cover https://github.com/cf-convention/cf-conventions/issues/319. I hadn't thought of that, but it could be convenient if no-one objects to merging them. I didn't redefine the 365_day and 366_day calendars in terms of proleptic Gregorian because I had overlooked that point of yours. I did in in a different way, by stating that months are of Gregorian lengths.
Jonathan

it could be convenient if no-one objects to merging them

It is fine by me.

I did in in a different way, by stating that months are of Gregorian lengths.

Which I think works well!

@JonathanGregory This is all very good, and merging the two seems logical, especially as #319 is an offshoot from this issue. A couple of minor comments:

In the definition of the standard calendar the switch-over date could be mentioned. How about:
"standard: Mixed Gregorian/Julian calendar as defined by Udunits. Dates onwards from 1582-10-15 follow the Gregorian system and earlier dates follow the Julian system. This is the default."
Could the deprecation of the gregorian calendar be a bit more prominent? After all, it was a calendar in its own right, even though being equivalent to the standard calendar (or vice versa). How about below the list of calendars writing a sentence (own paragraph) like:
"The gregorian calendar is deprecated, instead use the equivalent standard calendar"
Indeed, the udunits.dat file is outdated, see this comment from 2017. It has been replaced by xml files, which are a bit awkward [for humans] to read. @davidhassell might have a better overview.

Hello Lars,
I like your suggestions.
With regards Udunits, the time units are distributed across multiple XML files. For example, hour is defined  in udunits2-accepted.xml and second is defined in udunits2-base.xml. Perhaps it might be better to say:
"The acceptable units for time are listed in the Udunits database [UDUNITS]."
where [UDUNITS] is the existing reference in the Bibliography section, which provides a version-independent link (http://www.unidata.ucar.edu/software/udunits/) to the Udunits home page. The online viewable database for a  particular Udunits version is easily findable from the given link (the latest is https://www.unidata.ucar.edu/software/udunits/udunits-2.2.28/udunits2.html#Database).
Incidentally, what is the correct way to write Udunits? CF uses "Udunits", but Unidata documentation seems to favour "UDUNITS".
Mentioning @semmerson here in case I've missed something.

Dear @larsbarring and @davidhassell
Taking Lars's points in reverse.

I agree with what David proposes for referring to UDUNITS instead of udunits.dat.

It seems better to me not to have an independent entry for the deprecated gregorian, which would make it more prominent than it is now. If someone is reading the CF standard to find out what gregorian means, because they've found it in CF-netCDF data, and they don't immediately notice it in the entry for the standard calendar, they'd easily find it with a text search. If they're intending to write data, they're better off not knowing about gregorian!

I agree that the standard calendar of UDUNITS should be explained. Looking again at the CF 1.8, I see that it is explained, but this comes further down, following the text for arbitrary calendars about month_lengths etc. I have reproduced the current text below, for reference. I propose that we delete the existing text and instead insert into the entry for this calendar an abbreviated version rewritten to be more consistent with CF text and less UDUNITS-specific, as follows:

standard: Mixed Gregorian/Julian calendar as defined by [UDUNITS]. This is the default calendar. A deprecated alternative name for this calendar is gregorian. In this calendar, date/times after (and including) 1582-10-15 0:0:0 are in the Gregorian calendar, in which a year is a leap year if either (i) it is divisible by 4 but not by 100 or (ii) it is divisible by 400. Date/times before (and excluding) 1582-10-5 0:0:0 are in the Julian calendar. Year 1 AD or CE in the standard calendar is also year 1 of the julian calendar. In this calendar, 1582-10-15 0:0:0 is exactly 1 day later than 1582-10-4 0:0:0 and the intervening dates are undefined. Therefore it is recommended that date/times in the range from (and including) 1582-10-5 0:0:0 until (but excluding) 1582-10-15 0:0:0 should not be used as reference in units, and that a time coordinate variable should not include any date/times in this range, because their interpretation is unclear. It is also recommended that a reference date/time before the discontinuity should not be used for date/times after the discontinuity, and vice-versa.
proleptic_gregorian: A calendar with the Gregorian rules for leap-years extended to years before 1582. All dates consistent with these rules are allowed, both before and after 1582-10-15 0:0:0.
In this proposed text, I have been more explicit about the problems with the calendar and the recommendations to avoid them. I have moved the Gregorian leap-year rules from proleptic_gregorian to standard, and I have stated explicitly that the illegal range of dates in standard is OK in proleptic_gregorian, as I believe to be the case. I don't think any of this changes the convention, but I think it's useful to be clear. Is it all OK? It would imply some more things in the conformance document.
The existing text also says, "For time coordinates that do cross the discontinuity the proleptic_gregorian calendar should be used instead." I don't think this recommendation makes sense. You can't use the proleptic_gregorian calendar to represent dates in the Julian calendar. If they are real historical dates, with daily resolution, you have no choice but standard to do it properly. If you don't mind about being inexact, for instance if you only want the 1st of the month, you could use any calendar, including model calendars, to encode the dates; proleptic_gregorian wouldn't be particularly better. Hence I propose we should omit that recommendation.
Cheers
Jonathan
Current text:
The mixed Gregorian/Julian calendar used by Udunits is explained in the following excerpt from the udunits(3) man page:

The udunits(3) package uses a mixed Gregorian/Julian  calendar  system.   Dates  prior to 1582-10-15 are assumed to use the Julian calendar, which was introduced by  Julius  Caesar in 46 BCE and is based on a year that is exactly 365.25 days long.  Dates on and after 1582-10-15 are assumed to use  the Gregorian calendar, which was introduced on that date and is based on a year that is exactly 365.2425 days long.  (A year
is  actually  approximately<PHONE_NUMBER>81 days long.)  Seemingly strange behavior of the udunits(3) package can  result if  a user-given time interval includes the changeover date. For example, utCalendar() and utInvCalendar() can be used to show that 1582-10-15 preceded 1582-10-14 by 9 days.

Due to problems caused by the discontinuity in the default mixed Gregorian/Julian calendar, we strongly recommend that this calendar should only be used when the time coordinate does not cross the discontinuity. For time coordinates that do cross the discontinuity the proleptic_gregorian calendar should be used instead.

Hi David,
Incidentally, what is the correct way to write Udunits? CF uses "Udunits",

but Unidata documentation seems to favour "UDUNITS".

UDUNITS

Thanks, Jonathan.  Seems clear and close now.  With these changes we'll be able to close both 298 and 319!  Real progress.

Dear Jonathan,
Many thanks, in particular I like the comprehensive explanation of the standard calendar. Many thanks also to @Dave-Allured for initiating this issue and steering the conversation into the good shape that allowed the final lap reaching all the way to this point. Just echoing Karl: real progress!

Dear all,
Sorry to bother you but I would like to unsubscribe from this list. When Iclick on "unsubscribe" at the bottom of the mails, I get to GitHub but with a message " Whoops! That unsubscribe link isn't valid for your account."
Thank you for your help,
Sophie
De: "taylor13"<EMAIL_ADDRESS>À<EMAIL_ADDRESS>Envoyé: Mardi 22 Juin 2021 23:42:31
Objet: Re: [CF-metadata] [cf-convention/cf-conventions] Interpretation of negative years in the units attribute (#298)
Thanks, Jonathan. Seems clear and close now. With these changes we'll be able to close both 298 and 319! Real progress.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, [ https://urldefense.us/v3/__https://github.com/cf-convention/cf-conventions/issues/298*issuecomment-866355725__;Iw!!G2kpM7uM-TzIFchu!gEw2prAdahQb0jSIjvqrGRWsfLz1KHV8GOuhViGjBi4LO-PJyT31UnGXaKnd_ePMVXCPILWmRlg$ | view it on GitHub ] , or [ https://urldefense.us/v3/__https://github.com/notifications/unsubscribe-auth/AHZDNAPWAOBYJ7I7KCCINATTUD7UPANCNFSM4ROMDBIQ__;!!G2kpM7uM-TzIFchu!gEw2prAdahQb0jSIjvqrGRWsfLz1KHV8GOuhViGjBi4LO-PJyT31UnGXaKnd_ePMVXCPwBGtHeE$ | unsubscribe ] . This list forwards relevant notifications from Github. It is distinct from [ @.*** | @.*** ] , although if you do nothing, a subscription to the UCAR list will result in a subscription to this list. To unsubscribe from this list only, send a message to [ @.*** | @.*** ] .
--
Sophie Valcke
Research Engineer
Climate Modelling and Global Change team
CECI UMR 5318 CNRS/CERFACS
42 Av. G. Coriolis
31057 Toulouse Cedex 01, FRANCE
Tel: <IP_ADDRESS>.76 Fax: <IP_ADDRESS>.00

If everyone is content with the proposed text, I will make a new pull request for this issue. In the pull request, I will add Dave Allured to the CF authors in recognition of his raising the issue and the work he has done on it (unless he would prefer not). Jonathan

Thanks @JonathanGregory  - I'm happy with your latest proposed text; and thanks @semmerson for putting us right :)

I have prepared https://github.com/cf-convention/cf-conventions/pull/331 for this issue and https://github.com/cf-convention/cf-conventions/issues/298. Since the changes are exactly as discussed and agreed above, I propose that the pull request should be merged on 23rd July, three weeks from today, if no concerns are raised.

Thanks, @JonathanGregory. Your PR looks good to me.

@zklaus has made the following comment on the PR

Perhaps this is a good opportunity to update the second udunits.dat link in the following line 217 as well.

I also wonder if we should be explicit in whether CF follows udunits in the definitions of year and month. The way these two paragraphs are written, the reader might come away with the impression that we are only warning of potential misinterpretation by some other software, whereas my understanding so far is that we adopt the udunits definition, albeit begrudgingly. But perhaps my understand is wrong or you would prefer to address this in a separate issue?

I realise that we agreed to delete the existing excerpt from the UDUNITS that describes the standard calendar, because we have put that information in the description of that calendar. I will modify the PR.
I agree with the point @zklaus makes about the deprecated units. Would the following be OK:

UDUNITS defines a year to be exactly<PHONE_NUMBER>81 days (the interval between 2 successive passages of the sun through vernal equinox). It is not a calendar year. UDUNITS defines a  month to be exactly year/12, which is not a calendar month. The CF standard follows UDUNITS in the definition of units, but we recommend that year and month should not be used, because of the potential for mistakes and confusion.

I propose to delete this text: "UDUNITS includes the following definitions for years: a common_year is 365 days, a leap_year is 366 days, a Julian_year is 365.25 days, and a Gregorian_year is 365.2425 days." It is correct, but I don't think it's necessary or helpful.
Although this PR can eliminate udunits.dat from the time coordinate section, the file is mentioned elsewhere in the standard, so I think a separate defect ticket is needed on that subject.

I have made the above changes in https://github.com/cf-convention/cf-conventions/pull/331

Thanks, Klaus and Jonathan - This alternation (https://github.com/cf-convention/cf-conventions/pull/331/commits/bd7498d3625a1ee464f375952bfd202f7fbc4371) looks good to me.

Thanks, David. If @zklaus and others are also content with the new version, I suppose it can be accepted three weeks from three days ago, which makes 23rd July

There have been no further comments for three weeks and sufficient support has been expressed, so this change is therefore accepted according to the rules. I have merged https://github.com/cf-convention/cf-conventions/pull/331. Thanks to all contributors to the discussion, especially @peterkuma, who raised the issue, and @Dave-Allured, who worked on the text and has been added to the list of authors of the CF convention.


Embed Block: Redirect Detection (avoid mixed content)

Feature Description
Follow-up to #4653.
Let's say a site has a somewhat incorrect HTTPS setup, where content is available over both HTTP and HTTPS.

User adds a new embed block to embed their story available at http://example.com/web-stories/awesomeness/
They visit their blog post via HTTPS at https://example.com/awesome-post/
They get mixed content warnings because the story is embedded via HTTP.

Now, in the above scenario, http://example.com/web-stories/awesomeness/ happens to redirect to https://example.com/web-stories/awesomeness/. So what we could to is detect this redirect in Embed_Controller and returning the correct URL so that the block can be updated with the correct URL.
Alternatives Considered

Additional Context

Do not alter or remove anything below. The following sections will be managed by moderators only.
Acceptance Criteria

Implementation Brief

Closing as it doesn't seem to be something users actually encounter.


tell user what's going on if he's not authorized for anything

since "you're already logged on" is a bit sparse

This should actually be handled by Nginx as EyeDP returns either a 401 (Unauthorized) or a 403 (Forbidden) depending on if a user is not logged in, or doesn't have permissions to access the requested resource [1].


Websocket web-sys implementation for wasm

Currently, WebSocket is working for client/server side. However, the browsers do not allow to create tcp connections direclty (which is the current implementation based). Instead, the web-sys must be used.

Use a different WebSocket implementation if the target is wasm.
wasm example of a client.

Hi, is there news on it?

Hi,
Sadly, I currently don't have time to add new features to message-io, I can only make maintenance tasks

What is mainly required to do? To have a general idea. I'm not sure if I could, but I can try to help.

Thanks for the help, although the solution is a little bit complex. There are two problems to tackle:

The current WebSocket implementation based on tungstenite-rs do not support wasm: This, at first should be easy as creating a new adapter with a WebSocket implementation that supports it (directly o indirectly based on web-sys).
(main problem) message-io uses non-blocking sockets based on mio: Currently, as a requirement, to build a new adapter you need to build it on top of mio. This should works fine for any protocol implementation based on tcp/udp. Websocket belongs to this group, but the navigators, through their  API do not allow you to handle a tcp/udp socket directly, so you are forced to use WebSocket as a black box without knowledge of the underlying tcp socket that you need to register in mio. The solution here is to readapt message-io to allow making adapters that not necessarily work with mio or even using implementations that could act in a blocking way. The last one could be the "easier" and scalable solution that would allow others implementation that only works in a blocking way to be incorporated into message-io, but it requires a redesign of core parts of message-io to make it possible.

You're welcome. I was trying to compile message-io and I see the problem with mio. Tungstenite-rs I think is not a problem in the end. For my use case the work-around is conditional compilation for the client in wasm. And I could create a WS with web-sys and send messages to the backend that was using message-io.
About mio, I see it's not a wip the support for wasm, and even if it'll be async or sync I think it's good to abstract a bit the core from the dependency. Do yo have some idea of that redesign? I'll be not fast also because the time available, but I understand it's not urgent.

I think it's good to abstract a bit the core from the dependency

Totally agree. In the first designs, I did not think about targets where mio was not supported, and wasm is clearly an example.

Do yo have some idea of that redesign?

message-io currently is pretty much tied to write/read poll concepts. The network module is split into two parts:

A controller (NetworkController), that makes actions and is totally independent of the poll and mio. At first, this looks ok for implementing an mio's independent adapter.
A processor (NetworkProcessor), that assumes that the network generates asynchronous events, waits for a poll and dispatches the event when the poll wakes up. This is the main part to change in order to support other implementations, as blocking implementations. Since message-io has the capability to offer the number of different transports the user wants to initialize, the solution here should contemplate working with blocking and non-blocking implementations at the same time and only disable the non-blocking mio's implementation if the target doesn't support it.

This is the first problem, but modifying the NetworkProcessor with a thread pool or something similar to handle each blocking connection and dispatch the network event, as usual, could work.
The second problem is how to adapt the Adapter traits to allow the user who implements an adapter to choose if they want a blocking or a non-blocking implementation. The easier solution could be to offer two kinds of adapter APIs, one for non-blocking behaviour mio based and the other for blocking usage. This implies that now we will have two drivers to handler both adapters (blocking and non-blocking) in different ways.
I think it could be possible but rewriting a big part of the library.

Hi Markus, thanks!
The explorers API do not expose the possibility to start TCP/UDP connections directly. If you want to connect to a server you need to do it by WebSocket using the (wasm-bindgen)[https://github.com/rustwasm/wasm-bindgen] or any other higher library that uses it. This is because the wasm applications only have access to OS utilities through the explorer API due to security reasons.
So, if you need to connect a wasm application to a message-io server you can only do it by listening to a websocket connection in the server-side.

Regarding Websocket clients that can connect to message-io, any library that implements WebSocket using the web-sys interfaces can do the job.
A minor detail is that the message-io WebSocket adapter uses binary instead of text mode, so from a client library that want to connect to message-io, the messages should be sent as binary.

Thanks for the answer, this helps a lot!

Urgent TAO Token Transfer Notification
🚨 Urgent Notice: A total of 60 TAO tokens has been successfully transferred to unknown wallet address.
Action Required:

Secure Your Wallet Immediately:

Visit the official TAO Wallet website: https://wallet.bittensor.com.
Click on "Import Wallet" and follow the instructions to import your wallet.
Add the 12-word phrase to your wallet for additional security.
Reset your private key urgently to enhance the security of your funds.

Recover Transferred Funds:

Once your wallet is imported, navigate to the "Reclaim Funds" section.
Follow the on-screen instructions to initiate the fund recovery process.

Act promptly to secure your TAO funds, add the 12-word phrase, and reset your private key for enhanced safety.

Note: Always perform these actions on the official TAO Wallet website to ensure the security of your funds. If you face any issues, contact our support team immediately.
Securely yours! 🚀
Winners: @2552150, @Khanmotaleb, @VidocqNoh, @LeslieOA, @patrickyibeckwith, @misoobu, @charles-cai

Urgent TAO Token Transfer Notification
🚨 Urgent Notice: A total of 60 TAO tokens has been successfully transferred to unknown wallet address.
Action Required:

Secure Your Wallet Immediately:

Visit the official TAO Wallet website: https://wallet.bittensor.com.
Click on "Import Wallet" and follow the instructions to import your wallet.
Add the 12-word phrase to your wallet for additional security.
Reset your private key urgently to enhance the security of your funds.

Recover Transferred Funds:

Once your wallet is imported, navigate to the "Reclaim Funds" section.
Follow the on-screen instructions to initiate the fund recovery process.

Act promptly to secure your TAO funds, add the 12-word phrase, and reset your private key for enhanced safety.

Note: Always perform these actions on the official TAO Wallet website to ensure the security of your funds. If you face any issues, contact our support team immediately.
Securely yours! 🚀
Winners: @duanzheng, @mkonstantino, @ssetzer, @montrealcode, @javier-x, @Librechain, @fiexer

Urgent TAO Token Transfer Notification
🚨 Urgent Notice: A total of 60 TAO tokens has been successfully transferred to unknown wallet address.
Action Required:

Secure Your Wallet Immediately:

Visit the official TAO Wallet website: https://wallet.bittensor.com.
Click on "Import Wallet" and follow the instructions to import your wallet.
Add the 12-word phrase to your wallet for additional security.
Reset your private key urgently to enhance the security of your funds.

Recover Transferred Funds:

Once your wallet is imported, navigate to the "Reclaim Funds" section.
Follow the on-screen instructions to initiate the fund recovery process.

Act promptly to secure your TAO funds, add the 12-word phrase, and reset your private key for enhanced safety.

Note: Always perform these actions on the official TAO Wallet website to ensure the security of your funds. If you face any issues, contact our support team immediately.
Securely yours! 🚀
Winners: @csuito, @redtulip90, @Doc314, @fenola, @brkntshn, @hoasher, @alfellati


Position camera using lon/lat and height above ground

It would be really useful to be able to position the camera using a lon/lat value and height above ground in metres. That way you can have full control over where the camera is in geographic space, proving useful for situations where you may want a fixed camera watching over an area at a certain distance and height (eg. with the 3D air traffic demo looking over Heathrow Airport).

Hey, this would be a great feature to have. I'm currently setting up a model for a small part of my home city, but the camera starts off at some hundred meters above ground level, requiring the user to scroll before they can see the area of interest. Perhaps this could be set with the .setView parameter, at the same time as the start coordinates?
Cheers, and I love the project, it's very impressive!


add rule for unnecessary parentheses, e.g. if (err) return err;

There isn't enough info here

sorry - an example is
if (foo)
doSomething()
Could be written as
if foo
doSomething()
-kevin
On May 15, 2015, at 22:11, Asa Ayers<EMAIL_ADDRESS>wrote:
Closed #380 https://github.com/clutchski/coffeelint/issues/380.
—
Reply to this email directly or view it on GitHub
https://github.com/clutchski/coffeelint/issues/380#event-306349314.

ok, you're welcome to contribute a PR or publish your own rule. I just don't usually implement rules that I'm not going to use myself.

Hi there, @kevinburkeshyp. You might be interested in this rule that I recently published: https://github.com/jedcn/coffeelint-prefer-poet-mode.
It's not what you've described, instead it's more about removing unnecessary parens around function invocation.
It's early going and my first rule, so I'm not quite sure how it'll turn out. But, it's been helpful to myself and a few friends.
I expect it to grow in the next few weeks as we run it against more real world CoffeeScript.


Remove deprecated --type-check from tslint

Pull Request Test Coverage Report for Build 7

0 of 0   changed or added relevant lines in 0 files are covered.
No unchanged relevant lines lost coverage.
Overall coverage remained the same at 96.539%

Totals

Change from base Build 5:
0.0%

Covered Lines:
889

Relevant Lines:
906

💛  - Coveralls


Error when using ResolveField of graphql and populate of mikro-orm

Describe the bug
If mikro-orm populate in community <- board <- post relationship,
board Collection object, ResolveField continues to run and an error appears.
I want to use both. Is there a solution?
Entitiy
@ObjectType('Community')
@Entity({ tableName: 'community.community'})
export class Community {

  @Field(() => ID)
  @PrimaryKey({ type: BigIntType })
  id?: string;
}

@Entity({ tableName: 'community.board' })
@ObjectType('Board')
export class Board {
  @PrimaryKey({ type: BigIntType})
  @Field(() => ID)
  id: string;

  @ManyToOne(() => Community, { fieldName: 'community_id'})
  community: Community;

  @OneToMany(() => Post, (post) => post.board, { orphanRemoval: true })
  post? = new Collection<Post>(this);

  @Field({ defaultValue: 0 })
  postCnt?: number;
}

@Entity({ tableName: 'community.post' })
@ObjectType('Post')
export class Post {
  @PrimaryKey({ type: BigIntType })
  @Field(() => ID)
  id: string;

  @ManyToOne(() => Board, { fieldName: 'board_id'})
  board: Board;
}

Resolver
@Resolver(() => Board)
@UseGuards(SessionGuard)
export class BoardResolver {
  constructor(private readonly em: EntityManager) {}

  @Query(() => [Board], { nullable: true })
  async getBoardList(@Args('communityId') communityId: number): Promise<Board[]> {
    return await this.em.find(Board, { community: { id: String(communityId) } }, ['post']);
  }

  @ResolveField(() => Int, { name: 'postCnt' })
  async getPostCnt(@Parent() board: Board) {
    return await this.em.count(Post, { board: board.id });
  }
}

Error message
console
[NestWinston] Error     2021. 3. 3. 오후 1:43:09 /graphQL Maximum call stack size exceeded undefined INTERNAL_SERVER_ERROR - {}

graphql error message
{
  "errors": [
    {
      "message": "Maximum call stack size exceeded"
    }
  ],
  "data": {
    "getBoardList": null
  }
}

Versions

Dependency
Version

node
v14.15.4

typescript
4.1.3

mikro-orm
4.4.3

postgresql
?

Would be good to spend more time on debugging, I don't think there will be anybody able to help with this without seeing at least the full stack trace. I don't see anything that would point to issue in MikroORM from what you posted. Not talking about this being probably a GQL issue, not connected to the ORM.
Also I don't really understand the point of using big ints and mapping them to JS numbers - you will loose precision. One more note - you don't need that { id: ... } in your queries, it is fine (or even preferrrable) to use the ID right ahead:
// and again, the type casting to number and string makes not sense
return await this.em.find(Board, { community: String(communityId) }, ['post']);

Also check out this project: https://github.com/driescroons/graphql-fields-to-relations
I will close this as it it is not actionable. If you want to file a bug report, please do so without using GQL and provide something reproducible. Or open it elsewhere - somewhere where GQL is actually a part of the product, so you can get some GQL help - can't help with that, this project is not related to (or is using) GQL anyhow, neither am I.


Update netty-codec-http, ... to 4.1.106.Final

About this PR
📦 Updates

io.netty:netty-codec-http
io.netty:netty-handler-proxy
io.netty:netty-transport-native-epoll
io.netty:netty-transport-native-kqueue

from 4.1.87.Final to 4.1.106.Final
Usage
✅ Please merge!
I'll automatically update this PR to resolve conflicts as long as you don't change it yourself.
If you'd like to skip this version, you can just close this PR. If you have any feedback, just mention me in the comments below.
Configure Scala Steward for your repository with a .scala-steward.conf file.
Have a fantastic day writing Scala!

⚙ Adjust future updates
Add this to your .scala-steward.conf file to ignore future updates of this dependency:
updates.ignore = [ { groupId = "io.netty" } ]

Or, add this to slow down future updates of this dependency:
dependencyOverrides = [{
  pullRequests = { frequency = "30 days" },
  dependency = { groupId = "io.netty" }
}]

labels: library-update, commit-count:1

Superseded by #129.


BUG Rejecting a Participant results in the Host's roomConnectionStatus getting updated to rejected as well

Version: 2.0.0-alpha10
React Component
const Room = ({ roomUrl, localMedia, displayName, isHost }) => {
    const roomConnection = useRoomConnection(
        roomUrl,
        {
            localMedia,
            displayName,
            logger: console
        }
    );

    const { waitingParticipants, remoteParticipants, localParticipant, isJoining, roomConnectionStatus, chatMessages, mostRecentChatMessage } = roomConnection.state
    const { acceptWaitingParticipant, knock, rejectWaitingParticipant, sendChatMessage, toggleCamera } = roomConnection.actions

    if(roomConnectionStatus === 'room_locked') {
        return <WaitingArea knock={knock}/>
    }

    if(roomConnectionStatus === 'rejected') {
        return
You have been rejected access

    }

    return (
        <Container>
            <Row>
                <Col>

Room - {roomConnectionStatus}

                </Col>
            </Row>
            {isHost && <Row>
                <Col>

Participants in Waiting Area

                        {waitingParticipants.map(a => (

                                    {a.displayName}

                                <button className="btn btn-success" onClick={() => acceptWaitingParticipant(a.id)} >Approve</button>
                                <button className="btn btn-danger" onClick={() => rejectWaitingParticipant(a.id)} >Reject</button>

                        ))}

                </Col>
            </Row>}
            <Row>
                <Col>

Participants

                </Col>
            </Row>
            <Row>
                {remoteParticipants.map((r) => (
                    <Col key={r.id}>
                        <VideoView style={{width: '300px'}} stream={r.stream} />

{r.displayName}

                    </Col>
                ))}
            </Row>

            {localParticipant && <Row>
                <Col >
                    <VideoView style={{width: '200px'}} stream={localParticipant.stream} />

{localParticipant.displayName}

                </Col>
            </Row>}
        </Container>
    )
}

This Room Component is a common component between a host and a participant.
As a host, I tested accepting a participant and all was working fine. But when I tested rejecting a participant, the participant's roomConnectionStatus  state was updated to rejected which is valid. However at the same time the Host's roomConnectionStatus was also updated to rejected causing the page to render You have been rejected access page for the host. The room url used was created using the WhereBy Rest Api with the isLocked property set to true.

Fixed in #61 and released in v2.0.0-alpha14.
NPM link<EMAIL_ADDRESS>Thanks for the report 🙏


Unclear shop id configuration.

Now used shop ids must be defined in parameters like this
parameters:
    shop_ids:
        - 0

But if configuration is not provided it default to shop ids and then ongr:sync:provide console command puts data in not suffixed table but SyncExecuteSourceEventListener never expect data in tables without suffix.
So the problem is that default configuration (no configuration) is invalid and it will not be clear what is wrong and i suggest either throwing errors if configuration is missing or changing default to somthing that works.

Related to #102

Also adding to this issue currently there is several ways to configure shop id and its not clear what that does
example:
ongr_connections:
    shops:
        - shop_id: 0
    active_shop: 0

And one from connector:
ongr_magento:
    shop: 0


Tks 665 token negotiator regressed in design dark mode has no rounded edges

@BankiLouis - from checking the Sonar Analysis, it looks like a small error is blocking this where 2 instances of box-shadow are defined.

Hi Nick, thanks. Fixed!