John's little corner of teh interweb pipes thingy.

FOSDEM Wrap-up

I'm home from my first ever trip to FOSDEM and I'm pleased to say had a great time there, most of all because of the chance to meet up with so many fantastic KDE people.  I've never been to a conference with so many different FOSS groups involved and the vibe from so many geeks was incredible.  It was especially refreshing to see so many female contributors there and so actively involved in their communities.  I had planned to blog more about my impressions while there, but my laptop was quickly expropriated as the booth demo machine, and there was no free wifi at the hotel, so here's a long brain-dump of some random thoughts. You can see a few photos here.

I spent most of my time manning the KDE booth, more than I had planned and I missed a few talks I had wanted to see, but it was a pleasure to be able to interact with so many people, almost all of whom were overwhelmingly positive about KDE4.  I had only one "Amarok 2 sucks" (he didn't have the guts to tell Sven on the 'rok booth to his face though...), and one "I stopped using KDE after 4.0" but who was very keen to give 4.4 a go as he believes our technology is on the right track.  Much of my time seemed to be spent directing traffic.  There was the guy who wanted to get involved with the Windows port who I demo'ed stuff to in Virtualbox and referred to the Windows team.  Several people were eager to point out bugs they had found (directed them to bko). Others wanted to know if an obscure bug was fixed (err, I may be a dev, but I don't know every bug or feature). Someone wanted help with the openBSD packaging (hmm, dunno, Sune wasn't about, try Ade or the freeBSD guys?). Someone else wanted to know how to get the latest version of their app packaged by all the distros (talk to them at their booths just along the hall, or attend the OBS talk in 5 minutes time...).  Someone demanded to know why KDevelop had made certain design choices (palmed off on Milian, sorry!).  Someone else wanted to recruit some KDE devs to work on some desktop stuff (company business cards were quickly produced and handed over).  Someone wanted to know about colour management in KDE, so they got Boud's e-mail address :-)   An openSUSE developer wanted to check if a patch of his worked on my install (it didn't).  And the guy wanting to interview a Dutch-speaker for a podcast was directed towards Jos (poor soul ;-).

The best chat I had was with a guy from the Netherlands who walked up to the table and loudly declared "I Love KDE!" (no, not Paul).  He explained he was asked by a friend to help their mother with some PC problems.  He visited her at her retirement village and replaced Windows with Kubuntu.  A while later she asked him to visit again as some of the other residents wanted this Linux stuff too.  He refused to install it himself but instead he taught them to do it themselves.  Long story short, it spread like wildfire, last time he visited to give a talk there were over 80 very happy users aged 60 to 90 who had their own support community going.  They love Linux for how fast and stable it is, but also because they can play with it.  The beige box is no longer some mystery machine, but something they understand and control, and they are now contributing back to projects like OpenStreetMap and doing translations. Inspirational stuff.

For all the positives however, I think we can do some things better next time.

I know it's been talked about before, but we really do need a small demo machine with nicely pre-configured demo users that can easily be restored once messed up.  The obvious tricks we missed this time were to have an open-pc as our demo machine (cross promotion and sales opportunity there), an N900 running Qt/KDE stuff (the one on the Gnome table was constantly being pawed at), and a netbook to show off the new Plasma Netbook containment (I had planned to bring my eee but it died last week). And the biggest screen we can lay our hands on, with some kind of very flashy demo program running to draw people in (could we steal one from the openSUSE booth???).

We also need to give more thought beforehand to what we want to achieve with the booth.  Are we just there to sell t-shirts?  Or something more?  It's a decision we need to make for each event, and for FOSDEM I don't think the traditional "attract new users with a flashy demo" mode is going to work.  I think we need to focus on attracting new community members and interacting with upstream/downstream projects.  People mostly either wanted swag, or wanted to talk about technical stuff, there were no "What is KDE?" style questions.  These people are either already involved in a FOSS community and wanted to know how we can interact with them, or were looking to get involved.  Saying "visit the website" or "Google it" just doesn't cut it.  The "KDE Handbook" was hugely popular and we need more handouts like it.  We need to have "How can I help? / How to get involved?" handouts pointing potential contributors to the main participation entry points (wiki, mailing list, irc etc).  We may need some kind of (private?) KDE directory to know which person or mailing list project X needs to talk to about problem Y.   Knowing the areas of expertise of each KDE attendee would also be useful so you can grab an expert when needed.

There probably wouldn't be room, but rather than a table cutting us off from the people who wanted to talk, I think a "KDE Kafe" could work well at this sort of event.  Several chairs or beanbags, a few developers/translators/packagers/etc, a few demo workstations and laptops, free coffee for those who stop to talk, and lots of time to talk, network, bug triage and collect brainstorm ideas.

FOSDEM itself is impressively well organised, as you need to be with 5000+ visitors.  I'll just highlight two points, firstly their signage was very good, there was lots of it and it was very big, no getting lost here.  That's something I've always thought we could improve on at Akademy/Desktop Summit.  Not so good was the room allocation, where each project/stream got one room to use regardless of the size of audience each talk was likely to generate.  So talks about "What's in the KDE 4.4 Release" and "What's new in Drupal 7" in smaller lecture rooms were massively overcrowded and had to turn people away while bigger auditoriums next door on obscure topics were sparsely populated.  While staying in one room is good for a stream's more specialised topics, each major stream's keynote talk aimed at the mainstream could be given an auditorium slot.

Free foot massages for booth volunteers would be a welcome feature :-)

Fingers crossed, I'll be back next year, if only for the chance to eat waffles and drink beer at 11am while listening to a talk!

I'll take a double major in Plasma and Nepomuk, thanks...

I haven't seen it mentioned anywhere else KDE related, but in Madrid you can now take a uni course in KDE and Gnome programming.  I wonder if there will be guest lectures by Professor Faure and Dr Seigo? ;-)

Meanderings

It's been a few weeks, so what's up in the KDE Clapham office? (I'm pretty sure I'm the only KDE hacker in Clapham so can safely claim 'office' status, if I'm not, meet me for a pint down the Abbeville pronto!).

I'll be at Fosdem this weekend, so if you're there be sure to drop by the KDE stand for a chat, I promise not to bang on about calendars too much :-)  (Well, unless you happen to be a Gtk/Gnome/Evolution hacker wanting to talk about shared standards for calendars and holiday files, then I'm all mouth).  Just don't ask me about license stuff, you'll be wanting that weird bloke down the other end of the hall... I'll be in Brussels from 10am Friday wandering the streets in search of waffles, so if you're getting in early and looking for the same let me know.

Speaking of calendars (yeah, you knew it was coming) I decided on a whim to have a play with KHolidays in kdepimlibs to see if I could hack in support for holidays defined in non-Gregorian calendars, something I've been threatening the PIM guys I'd look at for ages.  After about a weeks intense hacking, cramming on Bison and Flex (blech!), and dredging up long suppressed university lectures on LALR grammars (it's been almost 20 years now!  And no, I didn't  understand Richard's last post either...) I had a new experimental parser working. I waved it in the direction of the PIMsters to see if they were interested and next thing I know I've been anointed a Maintainer.  Whoops, wasn't expecting that :-) So in 4.5 look for some improvements in how we handle holidays, in particular the ability to have non-Gregorian holidays like Jewish and Islamic religious holidays in the Plasma calendar and KOrganizer.

On that front, could I just ask for people in those countries and communities that use a non-Gregorian calendar to drop me a line with a list (or pointers to an official list in English) of both your official public holidays and the main religious holidays, and especially the rules about how they are calculated?  I'm particularly interested in the more complex to define holidays, the ones that need special or long calculations, so I can see if the new code supports them.  (We already have the KOrganizer Jewish Holidays plugin that I can crib from, but that's C++ and I'd like some English explanations).  I'm john @ my domain name.

Oh, if you use the Hebrew calendar, sorry I've messed up the Hebrew numbers support in 4.4, I should have a fix in place before it goes gold.

What else?  Oh yeah, there was some noise around the whole turn-of-the-decade thing, and Ade rightly pointed out we shouldn't be so pedantic about not having a year 0 to count from, especially with those 'lost' 10 days still to be found down the back of your sofa.  In fact it's worse than that.  It wasn't like on 1/1/1 that everyone suddenly woke up and decided "Hey let's start a new millennium!".  Nope, the Romans didn't even use proper year numbering.  It was some bloke called Dionysius Exiguus in 525 who came up with the idea to count consecutively from the birth of Jesus, except he got his maths wrong. And it wasn't until 731 that the Venerable Bede popularised using it. Later Gregory came along and decided to chuck away a few unnecessary leap days.   And somewhere in there New Years Day moved around various dates before settling back to 1st January. And...

So the whole year numbering scheme is entirely arbitrary and retrospective and open to being revised and refactored at will or whim.  As with the millennium, nobody's actually celebrating the passage of a fixed number of years.  No, we're all just looking at that car odometer click over to a neat line of 0's.  That's what we celebrate, and it's as good a reason as any for a beer.  Just imagine if we had evolved fewer fingers, we'd be doing it more often :-)  But if you really insist on being pedantic, then I will just point you at the ISO standard for calendars and dates where they arbitrarily declared the year 0 to exist for their purposes.

Speaking of which, my own clock ticked over to one of those 0's recently.  Life supposedly begins this side of the great divide, I'll let you know...

A reminder on GPL3 code in KDE

[Edit: revised version hiding my blushes by giving the right reason for the policy, it's nothing to do with Qt anymore, D'oh! :-)]

Licensing and license compatability is hard, and I'm no expert (that would be Ade...), but I do know that krazy is telling me there is an increasing amount of code turning up in KDE that is licensed only under GPL3 which is a no-no according to the KDE Licensing Policy.  The policy is in place because we need to keep our code base consistent and internally compatible while still allowing us to link to GPL2 only libraries if needed.

I'll be nudging people to get fixes made, but please remember that any new app code needs to be (GPL2+ || (GPL2+ && GPL3+)).  Any new library code (kdelibs, kdepimlibs, kdebase-runtime) needs to be (LGPL2.1+ || (LGPL2.1+ && LGPL3+) || BSD || MIT || X11) where appropriate.  This is just a high-level summary, read the Licensing Policy for the exact details, start the New Year with a refresher course :-).  Contact the licensing mailing list if you need expert advice.

Don't forget you must also include a copyright statement in the form "Copyright <year> <name of author> <e-mail>".  Although not explained in the policy, there's a few important criteria this needs to meet to carry maximum legal weight (at least according to discussions on the licensing list):

  • You must write the word Copyright, writing (c) has no legal standing, and the symbol © only has standing in some jurisdictions.
  • The <year> is the year you wote or changed the code, not the year you committed or released it.
  • Write out every year you modify the code, don't use a range like 2008-2010 as this apparently carries less weight legally.
  • The author must be a person or a legal entity such as a company or non-profit.  You cannot just say "The KFoo Team" as this has no legal weight, you have to name each author individually and the years that they modified the code.

So an ideal notice would look like "Copyright 2003, 2004, 2005, 2009 Joe Bloggs joe.bloggs@kde.org". 

I see a few people trying to beat the email harvesters by writing "joe.bloggs kde org", I guess that's still acceptable if a little futile? Please try make the email an address that will last a while: University, work, and even ISP addresses have natural life-spans far shorter than your code and someone may need to reach you 5-10 years later.  The kdemail forwarder is a good option if you are not an ev member with a kde.org address (hmm, about time I joined!).

Krazy is your friend for checking stuff like this, remember to look a couple of days after any commit to see if you've missed something :-)  I wonder if we could have an svn hook that runs krazy and apidox over only the files changed by a commit and e-mails the result to the committer? Or if all the checks would be too inefficient, at least an important subset?  All I know is most people forget to check krazy and apidox, so any automation would be good.

Happy New Year y'all!

Jalali Calendar updated

I've almost completed my QA review of the code in the existing Calendar Systems, with the Hijri / Islamic calendar passing relatively unscathed but some possible optimisations noted (it uses recursion where direct calculation may be faster).  The Jalali calendar (aka Iranian or Persian, as used in Iran and Afganistan) has proven somewhat harder and needed a lot of research.

The basic problem is that the Jalali is a purely Solar calendar with the first day of the year being officially defined in relation to the vernal equinox and solar noon at the reference longitude for Iran Standard Time (52°30' E).  There is no offically defined rule for calculating leap years, nor can there be, a leap year is just any year in which there are 366 days between successive vernal equinoxes.  The upshot is there is no simple arithmetic method to calculate when leap years should occur, for complete accuracy you must correctly calculate the vernal equinox.

There are two popular approximations for sequences of leap years, the 33 year cycle and the 2820 year cycle (aka the Birashk method), but these each return wrong results in various and different years, and there is much debate on which is better.  Most implementations choose to use one of these for efficiency and simplicity regardless of accuracy, Microsoft has chosen the 33 year cycle which is more accurate in years immediately around AD 2000, many FOSS projects have gone with the 2820 year cycle due to Emacs implementing it first.  I haven't confirmed which Apple supports.

In KDE we have been using the 2820 year cycle when calculating date conversions, but were using the 33 year cycle when calculating leap years, leading to some quirky errors. I've fixed that to always use the 2830 year cycle, and now restrict the valid date range to the years AP 1244 to 1530 (roughly AD 1865 to 2152), a useful range of modern dates during which the 2830 year cycle is only wrong twice (AP 1404 and 1437, roughly 2004 and 2058).  I've added special exceptions to cover these two cases so we now exactly match the true astronomical calendar for the entire supported period.

In 4.5 we should begin to support astronomical calendars properly, so we will switch Jalali to correctly calculating the equinox and thus extend the supported date range.  We will also provide reference implementations of the 33 and 2820 year cycle calendars to allow for interoperation with systems that use them.

The final calendar for QA is the Hebrew calendar, which looks to have had some bad bugs creep in.

Print Preview

One difference with the change in printing system to use Qt is that Print Preview is no longer available as an option from the Print Dialog itself (we used to have a little tick-box to say Print Preview).  Instead apps need to add an option for Print Preview to the File menu.  There are actually good usability and technical resons for Qt not hving this option available, but I just want to address the practical consequence of this: most apps no longer offer their users a way of doing a Print Preview.  Only Okular, KolourPaint, Kig, and KOrganizer have added the required Print Preview option to their File Menu (KOffice too, but they use QPrintPreview instead of KPrintPreview).

So this is a call to all apps that do printing to decide if you need to add Print Preview. Some apps it may not make sense, but if your app does any print rendering or painting that results in the printed output differing form the screen output then you should add Print Preview support.

It's real easy and shouldn't take 10 minutes to do, just add the Standard Action:

m_printPreview = KStandardAction::printPreview( this, SLOT( filePrintPreview() ), actionCollection );

then add your slot:

void KMyApp::filePrintPreview() {
    QPrinter printer;
    KPrintPreview preview(&printer, this);
    doPrint(printer); // Your existing print rendering code
    preview.exec();
}

Longer term, we will probably look to switch to the very nice QPrintPreview as KOffice has, but we won't for now as selecting Print from QPrintPreview produces a Print Dialog without the KDE enhancements.  Once the enhancements have been upstreamed then it will make sense to switch. Or maybe by then we'll have the OpenPrinting dialog ready which has an embedded dynamic print preview.

ISO Currency Code Support in KDE SC 4.4

I have previously posted that:

As part of my current localisation obsession, I've decided to pickup on an old wish list item to add support for the ISO 4217 Currency Code standard to KLocale.  Currently applications such as KSpread, KMyMoney, Skrooge, Kraft, KEuroCalc, and several Plasma currency converter widgets all have to maintain their own lists of codes and translations, which seems unnecessary duplication to me.

The good news is that after a few reviews and much help from the translation teams this feature made it in kdleibs for 4.4.  The easiest way to see what this involves is look at the System Settings Region module.  In the past, there was a simple lineedit that defaulted to a country's most common Currency Symbol and allowed the user to type in anything they liked.  It was simple and fine for merely formatting the occasional monetary amount for display, but pretty useless for apps working with multiple currencies or wanting to know a sane default: did $ mean USA or Canada or Australia or New Zealand or what?  Now KDE knows all the valid ISO Currency Codes, what the various valid symbols for them are, and even what countries the currencies are commonly used in, so the Region Money settings can now display combos to select the Currency by name and the Currency symbol:

Money settings

These new options make the Settings layout a bit long and crowded.  I had planned to simplify the Positive/Negative setting to a couple of combo boxes showing all the possible formats visually, but that will have to wait for 4.5.

The Currency combo gives you a list of all the available Currency Codes, with those used in the region prioritised at the top.  The example here is for Zimbabwe where the local Currency is currently suspended due to rampant inflation and the locals use anything trustworthy they can get their hands on:

Selecting a currency

Once you've selected your Currency, you can choose from the list of standard symbols for that Currency, here for the USD:

Select a Currency Symbol

This list is not translated, users are able to choose any commonly used symbol regardless of language or script, for example here is the symbol list for the Saudi Riyal:

Selecting other symbols

You will notice that the user no longer has the option to type in a symbol of their own choosing.  This is deliberate as I'm not sure we want the user to be able to type in a symbol that contradicts the chosen currency, i.e.choosing Japanese Yen but entering a Symbol of £.  The downside is that users who have personal preferences like extra punctuation or spacing are not able to have these anymore (well, not via the gui at any rate). I'll wait to see the user reaction.

Conversion to the new system is a little tricky.  If a user hasn't selected their own Currency Symbol and is using the region default, then everything is fine and they will just pick up the new default.  If they have selected their own symbol then we don't want to override that, but we also cannot tell what Currency Code they actually want (the ambiguous $ symbol problem again).  These users will continue to have their selected symbol used but with the (possibly contradictory) Currency Code of their region until such time as they go into the settings to correct things.

Another small addition is that KLocale now has separate settings for the number of decimal places for Money and Numbers instead of using the same setting for both.

Number settings options

If your code directly uses the old KLocale::fracDigits() method to obtain decimal places, please switch now to use either KLocale::decimalPlaces() or KLocale::monetaryDecimalPlaces() as appropriate.  I'll try chase them all down, but I'm not always sure which an app really wants. 

The benefit for coders from KCurrencyCode is mostly in having a common source of Currency Codes, symbols, and translated Currency names, which saves them creating and maintaining their own.  Have a look at the KCurrencyCode class in kdecore to see what's available and what you can use.  And don't forget that KLocale already provides a translation of all Country Names, there's no need to translate those a second time either.

A number of planned features didn't make it into this initial version, for example conversion and rounding rules.  I had hoped to have a 'fancy' money formatting routine to format $100.10 into "100 dollars and 10 cents" or even "one hundred dollars and ten cents" but there's a few translation issues that would need solving for that to be possible.

The 4.4 release comes with 204 Currency Codes, that is all currently valid Currencies in the ISO standard, and a number of major obsolete currencies for backwards compatibility.  For 4.5 there's another 85 or so obsolete currencies and other financial instruments that are defined in the standard that I could add, but that could just be an unnecessary burden on the translators so I'll make some judgment calls there.  If your app needs a particular Currency not yet available, then KCurrencyCode can be made to load your own config file.

Could I just ask for people in various countries to have a quick look at their own Currency and Country to make sure there's nothing wrong?  In particular, can you let me know if there are common variations for the symbols that are not yet supported?  The Currency config files are in kdebase/runtime/localization/currency and the Country config files in kdebase/runtime/l10n, or just run System Settings and have a play.

Dear lazyweb.se

My sister and I will be in Stockholm over Christmas and I thought I'd use/abuse the planet to get some info I can't find anywhere.  I know that 24th December is the big day, and the 25th and 26th are public holidays, and I know when the tourist stuff is open, but I can't find much info on when the practical stuff like shops and transport shut and reopen again.  Does the metro and other public transport run through-out?  What about transport to the rest of Sweden?  What days will the supermarkets / mini-markets / restaurants / cafes be open (we don't want to starve :-)?  And if you had the choice between staying in Gamla Stan or Fridhelmsplan, which would be better for the practical stuff like supermarkets and cheap restaurants?

Oh, and does it look like snow this Christmas? :-)

Thanks!

Going just a little krazy...

With the hard feature freeze in effect and everyone busy testing and polishing those features to a super shiny sheen, I thought I'd remind everyone that now is the perfect time to pop over to the EBN and check out your krazy score, especially if you've introduced new API in kdelibs that will be forever frozen once 4.4 goes gold.

In kdelibs we had 2436 code and 2792 apidox errors showing a week ago, which is way too many for our core libraries, especially the apidox which app developers rely upon, and the many licensing problems.  I've been hacking away at the low-hanging fruit this week while waiting on other compiles, but there's a lot there that needs the module maintainers attention.  If you can't actually fix something that krazy complains about due to BIC or API guarantees, or sheer necessity, then you can flag to krazy to stop complaining about it.  This is good practice, as it indirectly documents to others that you are aware it's a bad thing, but that it shouldn't be fixed.  Adding comments WHY you can't fix it is even better :-). You can find details about how to do that on TechBase. Let's see if we can get the kdelibs score below a thousand before 4.4.

Some of the easy fixes are a great place for new contributers to start and get familiar with the whole build and svn process, so I've started adding more detailed "how-to" notes on fixing them to the TechBase page, with a Low to High risk rating attached, and details of common false positives, etc.  Feel free to add more details, especially for the stuff I've got wrong or don't understand.

Oh, and please write more automated unit tests, especially if you have code in kdelibs, hmmkay?  Automated unit tests are gooood, they can save you from embarrassing mistakes, prevent regressions, and make it easy for others to maintain your code or do krazy fixes without breaking things.

What's that, Ade?  Oh, you want your whip back.  And the soapbox too?  Ahem, yeah, sorry 'bout that... ;-)

P.S.  One complaint about krazy, it flags "internet" as a spelling mistake, I think we stopped treating it as a proper noun back in the late 90's, didn't we?

Improvements to date formatting support in 4.4

In the past, kdelibs has only officially provided date formatting methods that supported the locale short and long date formats.  A number of apps found this rather restrictive and had to work around it with code like:

KLocale tmpLocale(*KGlobal::locale());
tmpLocale.setDateFormat("%d %b %Y");
QString dateString = tmpLocale.formatDate(aDate);

or worse like:

KLocale tmpLocale(*KGlobal::locale());
tmpLocale.setDateFormat("%d");
QString day = tmpLocale.formatDate(aDate);
tmpLocale.setDateFormat("%b");
QString month = tmpLocale.formatDate(aDate);
tmpLocale.setDateFormat("%Y");
QString year = tmpLocale.formatDate(aDate);
QString text = i18nc("long day number, short month name, long year number",
                     "blah %1 blah %2 blah %3", day, month, year);

or worst of all like:

const QString oldDateFormat = KGlobal::locale()->dateFormat();
KGlobal::locale()->setDateFormat("%Y %m %d");
QString dateString = KGlobal::locale()->formatDate(aDate);
KGlobal::locale()->setDateFormat(oldDateFormat);

(Messing with the global locale is a big no-no, no matter how briefly!  Code disguised to protect the guilty :-)

Well, in 4.4 your code can become a little simpler with native support for ISO date formats, more date component string methods, and a new formatDate() method that directly takes a C/POSIX/GNU standard format string without having to mess with a temp KLocale instance.  This gives a great degree of power over date formatting, but like the saying goes, with great power comes great responsibility, so please use with care and follow a few simple rules.

  1. In the first instance, you should almost always be using the locale Short and Long date formats in your user interface, as these are either the locale standard or the user's preference.
  2. If you do have specific needs in the user interface not covered by the standard formats and need to define your own date format string, then the format string must default to en_US format and must be made translatable to better fit your user's locale, e.g. so our American friends get the month before the day, the rest of us get it in the right order, and Japanese users get Kanji symbols instead of dashes, etc.
  3. If you are writing dates to file or wire, then you need to consider if it is safe to use the global locale to do so, as the Digit Set and Calendar System used may not be what you want, e.g. ODF and RFC both expect Gregorian Calendar System and Arabic Digit Set, but the global locale may be set to something different.  (This also applies to number and money formatting).

So what's changed, and how to use it?

The ISO standard date formats ISO Date (YYYY-MM-DD), ISO Week Date (YYYY-Www-D), and ISO Ordinal Date (YYY-DDD) have become first class citizens alongside the locale/user configurable Short, Long, and Fancy formats.  Use these whenever you want an ISO or RFC standard format date in the locale's Digit Set and Calendar System.

To output an ISO format date:

QDate testDate;
KGlobal::locale()->calendar()->setDate(testDate, 2009, 12, 1);
QString stringDate;
stringDate = KGlobal::locale()->formatDate(testDate, KLocale::IsoDate);        // "2009-12-01"
stringDate = KGlobal::locale()->formatDate(testDate, KLocale::IsoWeekDate);    // "2009-W49-2"
stringDate = KGlobal::locale()->formatDate(testDate, KLocale::IsoOrdinalDate); // "2009-335"

To read in an ISO format date from a string:

testDate = KGlobal::locale()->readDate("2009-12-01", KLocale::IsoFormat);
testDate = KGlobal::locale()->readDate("2009-W49-2", KLocale::IsoWeekFormat);
testDate = KGlobal::locale()->readDate("2009-335",   KLocale::IsoOrdinalFormat);

To directly set a date using the ISO Week and Ordinal dates:

KGlobal::locale()->calendar()->setDateIsoWeek(testDate, 2009, 49, 2); // Year, Week, Weekday
KGlobal::locale()->calendar()->setDate(testDate, 2009, 335);          // Year, Day of Year

To validate a ISO Week or Ordinal date:

KGlobal::locale()->calendar()->isValidIsoWeek(2009, 49, 2); // Year, Week, Weekday
KGlobal::locale()->calendar()->isValid(2009, 335);          // Year, Day of Year

The existing readDate() format string method has also been extended to read the ISO Week and Ordinal date components in any order or format:

testDate = KGlobal::locale()->readDate("Day 2 of Week 49, 2009", "Day %u of Week %V, %Y");
testDate = KGlobal::locale()->readDate("335/2009",   "%j/%Y");

Note that historically readDate() is not strict in applying the format string and will make best efforts to interpret the users input while obeying the input order, i.e. extra spaces are ignored, if the format string has long month it will accept the short month if entered instead, and vice versa.  I might implement a strict mode if there is demand.

If you just need a single date component as a string, such as day number or month name, in long or short format, then simply use the appropriate existing or new string method which will return the component in the users Calendar System and Language or Digit Set:

monthName()
weekDayName()
yearString()
monthString()
dayString()
dayOfYearString()    // New
dayOfWeekString()    // New
weekNumberString()   // New
monthsInYearString() // New
weeksInYearString()  // New
daysInYearString()   // New
daysInMonthString()  // New
daysInWeekString()   // New

To output a single date component:

stringDate = KGlobal::locale()->calendar()->monthName(testDate, KCalendarSystem::ShortName); // "Dec"
stringDate = KGlobal::locale()->calendar()->monthName(testDate, KCalendarSystem::LongName);  // "December"
stringDate = KGlobal::locale()->calendar()->dayString(testDate, KCalendarSystem::ShortFormat); // "1"
stringDate = KGlobal::locale()->calendar()->dayString(testDate, KCalendarSystem::LongFormat);  // "01"

Only if none of these options will meet your requirements should you use the new KCalendarSystem::dateFormat() routine.  Please read the extensive apidox for all the options available, but it supports most of the C / POSIX standard component codes as well as the GNU extensions for modifying the padding character and the padding width.  Note that a couple of the historic KDE format codes differ from the C/POSIX standard, in future I may add a fully compatible mode.

In use you should almost always translate the format string and include the kdedt-format keyword in the context:

QDate reportDate;
KGlobal::locale()->calendar()->setDate(reportDate, reportYear, reportMonth, 1);
dateFormat = i18nc("(kdedt-format) Report month and year in report header", "%B %Y"));
dateString = KGlobal::locale()->calendar()->formatDate(reportDate, dateFormat);

If you have to write dates to file or wire in a standard interchange format that always requires requires Gregorian and Arabic digits, then the easiest solution is to use QDate directly:

QString standardDateString = QDate.toString(Qt::ISODate);
or
QString standardDateString = QDate.toString("yyyy-MM-dd");

Alternatively, use the temp KLocale trick, but be very careful about just copying the global locale to start with, it's probably better to create a default one from scratch:

KLocale *standardLocale = new KLocale(yourCatalog, "en_US", "us");
standardLocale->setDateFormat("%a, %d %b %Y");
standardLocale->setDateFormatShort("%Y-%m-%d");

Note that reading in numbers and dates in any Digit Set is seamless, it's just writing them out you need to think about.

In general, if you write dates and numbers to file or wire, you may want to write unit tests to check your code still works with an alternative Digit Set and Calendar System set in the global locale.  If you use KMime's DateFormatter class for ISO and RFC dates then you should be OK.

The sharp-witted out there would have two thoughts going through their mind about the plea to always translate your date format strings:

  1. Why expose the full date formats for possible abuse when you could restrict the options using some format enum flags like formatTime() does and get invisible localisation as a result?
  2. Isn't language translation a poor heuristic for locale date format?  What about a Spanish-speaking American who will get the wrong format?

Well, we did look at using enums, but there were just too many variables to make it work simply without giving the translators hundreds of pre-defined strings to do, and it still wouldn't meet all the use case (see the reviewboard).  In the end it is better to trust people and encourage them to use the tools properly than to try impose restrictions they will just work-round anyway. And yes, it is a poor heuristic, but it affects fewer people than not translating at all. For 4.5 I am looking into a scheme to fully define the different rule sets for date formatting (e.g. American, International, European, ISO, Japanese, etc) and include these in each locale file to allow fully automatic construction of the format strings from enums with no pre- or post-translation required, but I'm not convinced it's possible or worth the effort for the few use cases we have so far.

I'll copy most of this onto TechBase for future reference.

Syndicate content