[HN Gopher] Reducing technical debt by valuing comments as much ...
___________________________________________________________________
Reducing technical debt by valuing comments as much as code
Author : ternaryoperator
Score : 55 points
Date : 2023-01-31 18:41 UTC (4 hours ago)
(HTM) web link (blogs.oracle.com)
(TXT) w3m dump (blogs.oracle.com)
| ternaryoperator wrote:
| The link at the end of the article to the JVM written in Go is a
| cool project. The GH project is at
| https://github.com/platypusguy/jacobin
| swatcoder wrote:
| Comments are _critical_ to long term project quality and
| consistency, but they 're always going to rot until tooling
| starts taking them seriously.
|
| For instance, it's great that code reviews have become standard
| practice at most organizations and for many projects, but the
| tooling for those reviews almost always rely on showing the few
| lines above and below a code diff. The reviewer has no convenient
| way of seeing how the changed code may conflict with any
| applicable comments unless the comments happen to be within those
| few nearby lines or the diff happens to include comment changes.
| Even then, the big picture is out of view and rot is still likely
| to seep in.
|
| It would be nice if incoming developer-support AI could start
| tackling this, by surfacing impacted comments and even "linting"
| them for applicability and accuracy.
| alexisread wrote:
| Even better if the language supports scoping comments to
| particular code blocks, and comments can be made in
| markdown/mermaid (or equivalent) so you can diagram, link and
| TODO comments.
|
| Documentation tooling should be able to make a good job of
| constructing a class/function DAG with scoped commentary. This
| is kind of a reversal of Literal documentation, but I suspect
| it may be more maintainable by teams.
|
| Literal docs only seem to go in one direction, that is
| documentation->code, not the other way around. This I guess is
| more in-line with scientific hypotheses. Literal tests may be
| even more tricky as TDD doesn't gel well with Literal
| hypotheses.
|
| I guess a Doc-driven dev process would be a novel approach
| here, and probably more usable than AI-supported systems.
| Copilot has been quite divisive on it's effectiveness.
|
| DDD in that every eg. Class requires a comment and a test even
| if they are blank, to force at least a thought about them.
| Having a code manifest at the root of a repo can also be used
| to configure the envs the code runs in, and the integration
| tests that it needs to do both local and in-place.
|
| Lastly, as mentioned elsewhere, logs are comments as well, and
| again would be well to be scoped in the language.
| cma wrote:
| Mayhe something like chatGPT could be fed diffs of a change and
| warn about comment rot and recommend fixes (once it has a much
| bigger context window).
| majikandy wrote:
| I love seeing comments in the code as they are usually the best
| entertainment I get all day. Especially when the code below it
| pretty much doesn't do what it says anymore.
| exabrial wrote:
| Unpopular opinion, but in the words of Linus, I have my asbestos
| underwear on so flame away:
|
| * Comments are excuses
|
| * They're used to validate the existence of crappy code
|
| * They do nothing for you in production
|
| Instead:
|
| * we commit to writing log messages... which are sort of like
| comments, but they work in production
| eatsyourtacos wrote:
| >Comments are excuses
|
| What the hell is that supposed to even mean? Then writing log
| messages are excuses too.
| weatherlight wrote:
| Not unpopular at all. This is totally sane. I wish more
| companies cared about good coding practices, code quality, and
| development life cycle. Things like comments made more sense in
| an era when there was no version control, no conventions around
| code style, no testing, etc.
| eatsyourtacos wrote:
| Hey everyone look, we have version control! That means there
| is no reason to explain anything!
|
| Version control, code style conventions, and testing have
| _nothing_ to do with explaining how something works or
| writing about potential pitfalls of this function if some
| other core logic were to change etc.
|
| Absolutely baffling you guys are arguing for never writing
| comments.
| weatherlight wrote:
| no one is arguing that.
|
| Comments are for things that are __impossible__ to tell
| from the code and the code alone.
|
| Comments are subjective, code isn't.
|
| 90% of the companies I've worked at have had commits linked
| to actual tickets in a ticketing system. if i really need
| to understand what was going on, holistically, i could just
| git blame and go there. i look at tests, I look at the
| discussion around the code between the person who reviewed
| the PR and the person who raised the PR. Too often people
| use comment incorrectly or noisily.
|
| No one is saying you shouldn't write comments. People are
| saying there are way better practices out there and you
| should really ask your self, why you are writing a comment
| to begin with and is there a better way to capture what it
| is your are trying to do so product managers, developers,
| engineering managers, QA people understand what the intent
| of that commit was.
| dbrueck wrote:
| Code captures only a portion of the thinking that went into the
| software's design. If you don't preserve the rest of that
| thinking elsewhere, you're forcing people to recreate /
| rediscover it later - and probably the most common way to do
| that is to throw away the code and rewrite it.
|
| So-called "level of intent" comments as well as comments
| highlighting tradeoffs, gotchas, flaws, limits, exceptions,
| assumptions, and so on, are incredibly valuable if you preserve
| them alongside the code. Comments explaining why this function
| exists and what it's for can help you quickly come up to speed
| on a new code base - this is especially helpful when it comes
| to handing off code to a new owner or expanding the team of
| owners. The following code may or may not be well written (who
| can say??) but it's not exactly inviting new contributors:
| https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/moti...
|
| Around the time of writing the code, comment-free code looks
| clear to the author because they have the benefit of all of the
| thinking that went into writing the code.
|
| I'd argue that in production is when comments are often most
| valuable. The middle of a crisis is a terrible time to wonder
| what assumptions were made when writing code a specific way, or
| if a certain line of code that seems to be doing something
| weird really is weird or if it was based on something you're
| not considering. It's also the time when you want to maximize
| the number of people that can jump in and help.
|
| Everybody has their own coding standards and there is certainly
| some subjectivity to those standards. Here's mine for people
| who work for me: if you don't document your code, you have no
| business touching anything that goes anywhere near production,
| you can't do anything that is critical path, and you should
| make a sincere effort to change or start looking for another
| job. :)
| twiddling wrote:
| Having done some "code archaeology" in my past, I loved coming
| across a good comment block, with clear rationale as to why
| something was done, which looked incorrect if you only had the
| code.
| davidw wrote:
| I worked with some Rails folks a while back who were utterly
| convinced that comments were to be avoided because it meant your
| code was not clear.
|
| I agree that comments explaining 'what' is happening are mostly
| useless. Write clearer code. But 'why' comments are good. Most
| things can be coded up different ways. Tell me why you chose this
| way. Tell me about constraints that might not be immediately
| obvious. Let me know if indeed, it could be cleaner, but you were
| in a hurry (this is a thing that happens in the real world), or
| if it's that way for a specific reason.
| claytonjy wrote:
| I worked at a late-stage Rails-based startup that had "dont
| write comments" as an engineering principle!
|
| The python folks before me used this to avoid writing
| docstrings for modules/classes/methods, so code could only be
| understood by reading the entirety of it. Throw in some deep
| class hierarchies and it was very hard to onboard there.
| adamwk wrote:
| I went from a rails developer to iOS; Apple and iOS developers
| in general are pretty good at comments, and I now value them
| more. Comments at the API level mean I don't have to go diving
| however deep to find out what a method does. If they're really
| good, they can also be used to distinguish the specification
| from what's actually happening when there are bugs.
|
| In the simplest cases, sure you don't need to write "getName
| returns a user's first name and last name separated by a space
| character," but I'm guessing the method requestPurchase will
| have a lot of nuance and I hope it's documented (yes, even the
| "what happens")
| rubyist5eva wrote:
| As a "rails folk", we aren't all like that :)
| ed-209 wrote:
| Small, well named functions have served me well in this regard,
| eg.
|
| if (theWhy()){ theWhat() }
| latchkey wrote:
| Document the why, not the what.
| collyw wrote:
| A lot of code is WTF enough that a comment explaining what it
| is attempting to do might be helpful. The real world is full
| of absolutely shit code, but it still earns the company
| money.
| latchkey wrote:
| Hmm... I think you might be missing the concept a bit. What
| I mean is that there is a lot of documentation that is like
| this: /* The phone number */
| private static String phoneNumber;
|
| That is considered 'the what', the documentation doesn't
| explain 'why' the phone number is a field on the class.
| This might be obvious because the class is called
| 'Address'... so people will argue that it is self
| documenting, and it is.
|
| The WTF code is 'the why'...
| corytheboyd wrote:
| Having worked with Rails folk for many years, they do have some
| weird strong opinions, this being one. The argument that
| comments shouldn't be made because they'll "become stale" is
| pretty lame IMO. It's either not a big deal or the end of the
| fucking world for some reason lol. Maintaining code is just...
| work. You just do it. That includes comments.
| mgkimsal wrote:
| > The argument that comments shouldn't be made because
| they'll "become stale" is pretty lame IMO
|
| Better not write tests either, because those will become
| stale too.
|
| And any sort of user documentation/support/etc. It'll all
| just become stale.
|
| It's almost as if code is just part of a larger 'thing' that
| has to be maintained.
| p1necone wrote:
| (well written) tests tend to fail (or fail to compile) if
| they're 'stale' though, so they force you to maintain them
| just like other code.
|
| (I'm not arguing against writing comments though - the
| 'they'll get stale' thing is not enough to make them not
| valuable)
| jrumbut wrote:
| The difference between tests and comments is that comments
| become stale silently.
| randomdata wrote:
| _> Better not write tests either, because those will become
| stale too._
|
| They do go stale, but tests were invented exactly so that
| your documentation is able to alert you when it has gone
| stale. Their existence rests on being an attempt to solve
| to this problem.
| BurningFrog wrote:
| When tests go stale the build goes red, and you know to fix
| things.
|
| Comments transition from truth to lie without any
| indication.
| vkou wrote:
| > Comments transition from truth to lie without any
| indication.
|
| Only if you don't do code reviews. The reviewer should be
| checking for this.
| still_grokking wrote:
| Only if you don't maintain your code.
|
| Guess what: Comments are part of the code. Like all other
| documentation!
| tcgv wrote:
| > Better not write tests either, because those will become
| stale too
|
| Unit tests are easier to maintain when incorporated to a
| CI/CD pipeline. Then every pushed commit (or Merge Request)
| will trigger the test suite to run and in case one of the
| tests fails the team will know.
| sky_rw wrote:
| Rails developers (myself included) are lazy by design, and
| thus eschew anything requiring redundant work. Most operate
| under the principle that "it was hard to write, it should be
| hard to read"
| citrin_ru wrote:
| Many people think their code is clear. The problem is it is
| clear often only for the author and sometimes for a limited
| time even for the author. If anyone else start to working with
| the code questions usually arise. And you can prepare comments
| for at least some of such questions.
|
| In my practice I often see code where useful comments are
| missing and hours of research required to learn something
| author for sure knew. Code which has too much comments to me is
| an imaginary problem - I've seen it at most a couple times in
| my career and one of them was the code written by a junior
| developer in a style one can expect in a tutorial or a book.
| But usually people quickly learn to not add unnecessary
| comments (and eventually start adding too little of them).
| weatherlight wrote:
| Many people think their subjective comments are clear! Code
| doesn't lie, comments do.
| MrGilbert wrote:
| Yet, code might not tell the whole story. It's a pitty.
| afandian wrote:
| I wouldn't use the word 'lie' but plenty of Rails code I've
| seen has mystery effects and hard to follow coupling due to
| monkey patching and the like. Comments please.
| lordgroff wrote:
| So train people to write better comments, because although
| code doesn't lie (questionable as that is since the intent
| behind the code and what it does doesn't always align) it
| can be literally the worst implantation of an algorithm
| imaginable, and so we teach people how to code.
|
| Teaching people how to comment is a skill that's just as
| important and nothing turns me off a project faster than
| the "code is its own documentation" mantra.
| weatherlight wrote:
| If this study is to be believed. Citation->
| https://cacm.acm.org/magazines/2017/10/221326-a-large-scale-...
|
| The 5 programming languages with the least amount of bugs are:
| Haskell Ada Scala Rust
|
| *Drum roll please* Ruby
|
| Ruby is nothing like the other languages above in design, but
| that community has fantastic conventions around code clarity,
| code quality, testing, continuous integration, etc.
|
| Comments are for things like, `Todos`, Noting a specific
| algorithm, maybe a link to a white paper, noting a violation of
| a convention for speed, security, or some other performance
| reason.
|
| Comments are for things that are __impossible__ to tell from
| the code.
| tln wrote:
| Interesting paper, thanks for posting. The paper goes on to
| say:
|
| > One should take care not to overestimate the impact of
| language on defects. While the observed relationships are
| statistically significant, the effects are quite small.
| Analysis of deviance reveals that language accounts for less
| than 1% of the total explained deviance
| otikik wrote:
| Agree with most of what you said, except on the
| __impossible__ part.
|
| You can tell _everything_ with code, _given enough time and
| resources_. Nothing is "impossible". But there's a point
| where you hit diminishing returns. It's about efficiency.
|
| Other devs, or your future self, will have to time trying to
| build the same "castle in your head" as you did. Can a
| comment shorten that time? If a one-line comment saves 15
| minutes of investigation in aggregate, that's a no-brainer.
| You should add it. Conversely, a line that says "add 5 to x"
| is just wasting everyone's time.
|
| As a general rule, once I have finally understood a
| particularly hairy piece of code, I don't want to do it again
| in 6 months. I have even done ASCII diagrams in the comments
| explaining how a particularly hairy piece of code worked,
| when I hated it enough.
| lumb63 wrote:
| In my experience, one man's "waste of time" is another
| man's castle-in-the-head-building-time-saver. At my current
| company, if I have reasonable, self explanatory code, such
| as a function with the signature "read_page(page_num: u32)
| -> PageData", they'll gather it reads a page with the given
| page number and extracts the data. At my last company, if I
| wrote the same code, I'd receive a comment on my PR
| complaining I did not document it will enough. I would then
| add a comment that somehow only I was able to detect was
| snarkily written, something like "// reads the given page
| number and returns its data" and they would be happy as
| clams.
|
| I always assumed that behavior was dogmatic until, over
| many PRs, multiple members of the team commented that if I
| commented my code, it would be much easier to read. And
| comments of the above quality assuaged them.
| jofer wrote:
| ASCII diagram comments are surprisingly common in
| scientific computing, FWIW. It's not so much that it's
| always hairy code, more that it helps to add some
| visualizations of what's going on. Math vs intuitive
| understanding are often very different things.
|
| It's something I wish was more common than it is. Sometimes
| you really want that ASCII pseudo graph explaining how
| minimizing this thing relates to that other thing that we
| actually care about.
|
| Taken a step further, I really wish we had better systems
| for managing this type of information alongside a codebase.
| E.g. the whitepaper, or presentation, or figures, or
| whatever is often very necessary to understand the code,
| and ideally it would be under version control and live
| neatly alongside things. Nicely rendered docs definitely
| help with this (e.g. latex in comments), but I'm always
| surprised there aren't more people focusing on this aspect
| of information management.
| jaywalk wrote:
| I wish I could get this point across to my team. They will
| happily write:
|
| db.insert(record); // save the record to the database
|
| But when they write some crazy off-the-wall code (that's
| usually because they didn't understand the proper way to do
| something) I have to check the logs to see who wrote it and
| ask them why.
|
| Just the other day I was debugging an application that had a
| 6 second sleep at the end of the main() function. I just
| figured it was some dumb thing left in for debugging and
| deleted it, because there's no good reason to do that. The
| next day, the dev who put it in messaged me and said he put
| it there because the application was exiting before it had
| logged it's completion to our logging system. So I explained
| that the proper way to do this is to flush the log, not just
| hang the application for 6 seconds so that the last messages
| just happen to go through.
|
| If there was a comment explaining _why_ there was a 6 second
| sleep, I could have just fixed it and educated the developer
| without causing any grief.
| weatherlight wrote:
| thats a legit case of, "its impossible to gleam that fact
| from the code and the code alone." (although I would have
| left that as a comment for the reviewer in the PR) so if
| theres a conversation around that decision, it would have
| been captured there.)
| j45 wrote:
| Comments are critical at creating beginners to the code base,
| something rarely the expert class think about accelerating.
|
| For my code? I agree
|
| Code for others to participate in? The simplest possible way
| for the greatest number of developers to understand as
| quickly as possible. Not about my best practice or preference
| but for the greater good.
|
| Coding standards for the elite devs are only so effective at
| growing that growing quick enough.
| paulddraper wrote:
| What question will the next engineer have about your choice?
|
| 1. Rewrite your code to make the answer obvious.
|
| 2. If that's not possible use a comment.
| randomdata wrote:
| _> I worked with some Rails folks a while back who were utterly
| convinced that comments were to be avoided because it meant
| your code was not clear._
|
| What this means is that if your Ruby code is clear it should
| read like natural language. Injecting subtitles into the middle
| of the expression
|
| # I decided to phrase it this way because I was in a rush and
| it was the first thing that came out. With more time I could no
| doubt articulate this in a more communicative way, but for the
| sake of a random post on the internet I'm not terribly worried.
|
| interrupts the flow when one is reading the code, which makes
| for a much less pleasant experience. Ruby may not be the only
| language that is like this, but it is relatively unique in this
| regard. Comments in other languages don't seem to cause the
| same interruption.
|
| # That's all I've got. Time to clean up.
|
| I'm not sure this means don't provide additional information to
| future readers that may be beneficial, but be discriminating in
| where you put it.
| davidw wrote:
| > should read like natural language
|
| The history of programming is full of that notion and it
| never really works out. See: COBOL, SQL, and so on.
|
| I think we can all agree that code that is easy to read is
| better, but sometimes the 'why' needs spelling out.
| randomdata wrote:
| Totally agree. I even said so at the end. You would have
| noticed if the comments didn't get in the way. :)
| kawsper wrote:
| Arkency, a very well-known Ruby consulting company (at least in
| Europe), are the ones I've seen shout about this 'rule' the
| loudest: https://twitter.com/arkency/status/1254784379190038534
| latchkey wrote:
| My time at Pivotal Labs was similar. "The tests are the
| documentation!"
| vkou wrote:
| Oh? Their tests have 100% coverage of _every_ feature, and
| _every_ meaningful interaction between features?
| Yoric wrote:
| I have worked with a few developers who shared this motto.
| I didn't agree with them.
|
| While it's anecdotal, my understanding is that we were
| simply working on very, very different codebases. I was
| refactoring multi-million lines C++ codebases, implementing
| concurrent algorithms in which dependencies cannot be
| expressed through language constructs and I had to make
| non-trivial choices to prioritize performance, or safety,
| or security at the expense of readability.
|
| On the other hand, these (few) developers were working on
| writing fresh code, with less footgunny languages, with
| simpler data and control dependencies and didn't need to
| make hard choices due to perf/safety/security.
| zabzonk wrote:
| i think comments can be very useful. for example, look at the c
| function strlen:
|
| int strlen( char * s );
|
| the following comment pretty much describes what it does:
|
| - if passed a null-terminated string, returns the number of
| characters in the string, excluding the terminator
|
| - if passed a null pointer, or an incorrectly terminated string,
| behaviour is undefined
|
| these are the kind of comments i like to see
| catskul2 wrote:
| I feel statements like:
|
| "...team leads (and managers) allow comments to get out of sync
| with the code..."
|
| reveal a fundamental misunderstanding of how software
| organizations generally work.
| simonbarker87 wrote:
| I've always pushed back against the "no comments, they go out of
| date" sentiment.
|
| Comments aren't milk, they don't just go off, developers let them
| go out of date.
|
| As others have said, comments should be used to add why, to give
| context.
| SpeedilyDamage wrote:
| Why must that documentation go inline with the code? There are
| so many better ways to document design and implementation
| decisions that don't involve embedding English into source code
| files.
|
| We preach endlessly the idea of orthogonality and abstraction,
| but then we smash together plain English and
| Python/C++/Erlang/whatever?
| simonbarker87 wrote:
| If the information in the comment directly relates to the
| code and is for developers then putting it next to the code
| makes a lot of sense. Putting it somewhere else just
| increases the likelihood it will go stale and decreases
| discoverability of the information.
| randomdata wrote:
| 'Why' should be documented in your test suite. Leave a comment
| too, but don't think you can skip out on the former because
| you've done the latter.
| citrin_ru wrote:
| Tests can show what code is expected to do from the point of
| view of the tests author. They usually have no information
| why code works this way. Also I've seen more than a few times
| tests which ossify wrong behavior. Tests need comments too.
| randomdata wrote:
| _> They usually have no information why code works this
| way_
|
| They need to if the the way it works is significant. If it
| is not significant then the value of a comment becomes
| somewhat dubious anyway as the code is expendable and
| doesn't really matter. It is not necessary to understand
| the program and if it is flawed you're going to rewrite it.
| Comments can add a lot of value, but there is a line where
| the value quickly diminishes.
| doctor_eval wrote:
| > Because the culture of many development organizations
| undervalues comments, team leads (and managers) allow comments to
| get out of sync with the code--thereby increasing technical debt
| instead of reducing it.
|
| Comment bit rot is inevitable, because comments don't compile and
| can't be tested. The only way to keep them in sync is by hand,
| which takes a lot of time and energy and is far from perfect. Of
| course,
|
| > The first problem is that most developers are under great time
| pressure and don't have the time to make the code so utterly
| clear that it requires no further comment.
|
| So they don't have time to write the code clearly, but they
| somehow magically have time to read and review all the comments
| and to keep them in sync with the code? And the reviewers too?
|
| "If only developers worked harder...". It's nonsense.
|
| Comments are great, they have an important place in software
| engineering, and I always regret when I forget to write some in a
| file or class. But they are not a silver bullet, and must be
| treated with suspicion, because there is no way to prove if they
| actually describe what's going on. And that's the same reason
| that they are hard to keep in sync.
| SpeedilyDamage wrote:
| If I've written a comment, and I have, it's because I have to
| move on, _not_ because I think it 's adding an extra layer of
| quality.
|
| I don't _want_ to write a comment, I 'd _rather_ write clean
| code that looks good, but when I run out of time to spend on a
| problem, and I don 't think the code is clear enough, I think
| _then_ it 's acceptable to add a comment.
|
| I just think too many devs have their egos wrapped up into
| their jobs, so hearing, "Commenting is failure!" evokes an
| emotional response. What these devs don't realize is you can
| make no mistakes and still "fail" to write clean code, and
| that's totally okay.
|
| Uncle Bob is just saying that pulling out a comment before
| you've tried is premature. Try to avoid it first, if you have
| time to.
| jonfw wrote:
| Great thing about Git, is you can look at the code at the time
| when the comment was written, and still retain the original
| value of the comment.
|
| If there have been major structural changes that make the
| comment useless- that'd be pretty easy to see, it's very easy
| to delete comments
| revskill wrote:
| It's time to get comment generated via toolings.
| ChrisMarshallNY wrote:
| I have come to a "middle ground," when structuring and commenting
| code.
|
| First, the code needs to be fairly clear, but not "stupid" clear.
| I have had people tell me not to use idiomatic Swift, because "a
| JavaScript programmer can't understand it."
|
| In some cases, this may be necessary, but not in mine.
|
| The #1 consumer of my code, is Yours Truly. The wonkiness doesn't
| bother me, but sometimes, I may not be aware of _why_ I did
| something (that may not be "idiomatic," at all).
|
| That's why I may write a quick comment, like so:
| showThrobber() // The reason for this, is that we
| need to give the throbber time to show up.
| DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() +
| DispatchTimeInterval.milliseconds(20)) {
|
| That explains the awkward use of an "asyncAfter()" method.
|
| It was the result of me, wasting a good half hour, trying to
| figure out why the screen didn't change. I saved future me, a
| half hour (and also a signpost for "improvements needed").
|
| I write about my approach to documentation, here:
| https://littlegreenviper.com/miscellany/leaving-a-legacy/
| MSFT_Edging wrote:
| I always write comments, even on code I've written myself it
| comes in handy.
|
| 6 months later I wont remember why the "easy" solution wasn't the
| path that was taken, or some complexity that needed special
| handling in a single case that was discovered through a few hours
| of debugging.
|
| Sure you could write perfect code, but writing out your thought
| process helps tremendously with understanding a thought process
| and getting up to speed far faster.
| alyandon wrote:
| Same - if my code is complex enough to not be easily written in
| a few lines I'll drop a comment about what it is doing and
| maybe even why. It takes a minimal amount of effort while I'm
| coding and saves a lot of time when I (or someone completely
| unfamiliar with the code) have to revisit it months/years
| later.
|
| My guiding principle is that I don't want someone to read my
| code years later, exclaim "Who the hell is this alyandon
| guy?!?!" and be motivated enough to create a time machine so
| they can go back in time and smash my keyboard to bits before I
| wrote said code.
| collyw wrote:
| Likewise if I am using some advanced feature of the language
| / framework, I think it's worth a comment.
___________________________________________________________________
(page generated 2023-01-31 23:00 UTC)