PlanetKDE

warning: Creating default object from empty value in /home3/johnlayt/public_html/modules/taxonomy/taxonomy.pages.inc on line 34.
Include on RSS feed to PlanetKDE

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.

Ethiopean and Coptic Calendar Systems for 4.4

Another update on the Calendar Systems.  Last time I mentioned I was moving onto the Bahai'i calendar.  Well, that proved to have some problems (see below) so I moved on to something easier, the Ethiopian and Coptic calendars which will be 4.4.  These are nice, straightforward calendars based on the ancient Egyptian calendar.  These have 12 months of 30 days followed by a separate epagomenal period (effectively a short 13th month) of 5 days or 6 days in leap years which are every 4 years, which makes the whole calculation very simple indeed. 

The only differences between the Ethiopian and Coptic calendars are the epoch and the names of the months and weekdays, so it's effectively a two-for-one deal.  The hardest part was finding the right English versions of the Coptic and Ge'ez names, which I hope I've got right as there were several versions to choose from (quick apologies to the translators for forgetting to give them a heads-up on the tricky strings involved).  I don't know what the FOSS market-share is in the Ethiopian or Coptic communities (Google doesn't reveal anything much), and we don't have a Ethiopian translation project, but it's one less barrier they might have to negotiate in the future.  It's highly unlikely we will ever have a Coptic translation with only 300 speakers worldwide, but the calendar itself has a wider use.

Pics of the Ethiopian and Coptic calendars, notice the short epagomenal period showing in the Coptic one.

Ethiopian calendar

Coptic calendar

Funnily, while OSX has locale support for different calendar systems including both Coptic and Ethiopian, Apple's own app programmers don't seem to have got the memo, spot the bugs in iCal:

OSX iCal not getting calendars right

One bug we did have that I've fixed for 4.4 is RTL support in the Plasma calendar table:

Plasma calendar in RTL mode

The Bahai'i calendar proved harder than I expected.  It's interesting as it has 19 months of 19 days each, and a separate epagomenal period of 4 or 5 days.  That would be easy enough, except the epagomenal days are not at the start or end of the year, they are placed between the 18th and 19th months and in practice appear to be written down as month 0.  So how do we do that?  We could just label the epagomenal days as month 19 and month 19 as 20, which is good maths but bad usability, as would treating the epagomenal days as part of the 18th month.  It seems there's going to have to be some magic going on between the user interface and the actual calculations, but that could mean every widget that shows/reads dates will need rewriting to know what to do.  Nope, that's out too.  In emacs they treat them as prefixing the 19th month, so are entered as negative days in the 19th month, i.e. -03/19/2009, which would break all our existing validation and formatting code.  Which is about when I gave up and moved on to something easier :-)

In the comments on my last blog, someone mentioned that supporting the Japanese Emperor Era calendar should be easy as it is just the Gregorian Calendar but with the year instead of being counted since the nominal birth of Christ (i.e. AD)  being the number of years into an Emperors reign.  If only it were that easy :-)  The big problem is that everything in KCalendarSystem assumes an 'absolute' year' in a continuous integer range from -9999 to 9999 (with an optional year 0), we make no allowance for the entry or display of an era for the year to start counting from, nor does the C/POSIX format codes have a value for era.  Supporting Era style calendars would require adding new virtual methods to the API for era() and eraYear(), code to convert between era years and absolute years, and changes to the date reading and formatting code to do the translation.  That's a problem, as the KCalendarSystem base class has no virtual table slots left to add new API.  There's ways around that, but it's going to take careful planning.

Finally, I've started planning for the lunar calendars in 4.5 by purchasing a copy of the bible of astronomical calculations which has special chapters devoted to calendars.  I need to determine exactly what calculations we need to be able to perform, and how complex they are to implement and support.  If they're relatively few and simple, then we can have our own or borrowed implementations directly in kdelibs, if not we need to either find existing implementations to (optionally) depend upon, or work with another project for them to support.  Possible sources of code include KStars, the Plasma sunrise/sunset data engine, or libnova (which KStars already uses).  Possible new homes could be a version of Marble in kdesupport (if that ever happens?), a separate library in kdesupport, or an outside project like libnova.

On the upgrade cycle

It's that time of the year again when the openSUSE RC's are hitting the net and I can enjoy a fresh re-install.  This time round, I also had a fresh new copy of OS X Snow Leopard to upgrade to (no, I will NOT be upgrading my XP install to Win7 as well).  The plan was just to upgrade in place, but my GPT partition table was somehow corrupted and Snow Leopard was throwing a fit refusing to recognise the partition (funny, openSUSE had no such problems) so I was forced to fully wipe the drive.  This meant actually having to back stuff up (yes, I know...), and having no space left on my 5 other external drives (700Gb) I bought myself a new 2Tb external drive for the purpose.  2Tb.  On my desk.  Just sitting there not much bigger than a paperback. Man, I still remember my first ever hard drive, all of 20Mb that was, shoe-horned into my Amiga 1200.  I remember my work sending me on a training course in the mid-90's for Teradata databases (special parallel hardware required!) and wondering what could possibly need that much storage.  Fifteen years later I now know :-)  Anyway, enough of the past: Snow Leopard purred on nicely albeit rather slower than openSUSE which took almost no time at all.  Windows, well I'm not in a mood for that re-install re-boot hell quite yet...

openSUSE looks really slick, and does run a lot faster and smoother than 11.1 (but that could just have been my messed up GPT and all the residual crud from messing with stuff).  The guys have done a brilliant job with this release.  Where I'm disappointed once again is in the out-of-box hardware support for my Macbook which still falls short with few of the problems from 11.1 having been solved.  I'm still investigating if this is a universal Linux thing or just openSUSE not configuring stuff right.  The touchpad is not configured correctly (no right-click, let alone multi-touch), there's no keyboard lights, and the screen dimming appears to still only work via nvclock.  Sound now works without messing with config settings, but the heaphone socket still doesn't cut the speakers.  My biggest annoyance so far is that X doesn't correctly detect the Macbook's UK keyboard or my external Mac UK keyboard.  Instead, I have to run sax2 and hit cancel and I get the right keymap again (at least until the next reboot, I don't want to click save as it screws up my dual monitor setup).  I'm sure I'll be able to tweak the settings to get it all working eventually, but it's just annoying when I have better things to do with my time.  Perhaps I need to gift one to the openSUSE team to play with?  Just kidding, I can't afford that right now, maybe next hardware upgrade :-)  As usual, I'll update the openSUSE on Macbook wiki page with my results.  I've already cleaned up my general Linux/openSUSE on Mac notes which includes good info on partitioning and how to triple-boot Linux/OSX/Windows.

I haven't had much time to mess with Snow Leopard yet, but I did take a quick peek at the localisation options, and it looks like Apple have also been upgrading their Calendar System support by adding Coptic, Ethiopic, Indian National, Persian and Chinese.  So, game on Mr Jobs :-)

ISO Currency Code support

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.  I've posted a design on TechBase and an implementation on Review Board for people to have a look at, so if you work on one of the financial apps that might use this then please have a look and comment (I tried e-mailing everyone, but I've got some bounces).

One thing I learned that I never knew before (besides lots of esotoric facts about currencies like there are only two non-decimal currencies left) was that some countries group their digits in different size groups than thousands.  In India for example, they group their digits in groups of two except for the smallest group which is a group of three, i.e. 00 00 00 000 instead of 000 000 000.  In China and Japan they use groups of four.  POSIX already has a format definition for this in LC_NUMERIC and LC_MONEY so Gnome probably supports it, and Windows supports it, so I guess that's another item on my TODO list :-)

Calendars Around The World

The other hat I wear around these parts besides Printing is Calendar Systems (just don't ask how I got interested, a long story...), and I've found a bit of time to put some more work into them, as well as the plasma Calendar and Clock widgets.

I've posted previously about giving the plasma Calendar and Clock widgets the ability to set what calendar system to display.  This is now in trunk for people to play with, so I thought it was time to add to our already supported list of calendar systems that people can display on their desktop.

My first target was the Indian National calendar, the official government calender for India, albeit one apparently not widely used (the Gregorian is the common civil calendar).  While the various Indian religious calendars might be more useful in daily life, unfortunately these require various astronomical calculations that we don't yet support, or local observations that we may not be able to support.

The Indian National calculations on the other hand are fairly straight forward as it is very closly linked to the Gregorian calendar, with there being a fixed 78 year difference in the year numbers, a fixed 80 day difference between the start of the respective years, and synchronised leap years.  One interesting feature is that the first year in the calendar is Year 0, which required some changes to the base class to support as none of our current calenders have one.

The big problem though was that our exisiting Gregorian calendar class copies QDate in only actually doing Gregorian calculations after 15 October 1582, before then it uses the Julian calendar calculations.  Any earlier dates in the Indian calendar would be calculated wrong if I used that, so I first had to implement a 'pure' version of the Gregorian calendar to use as a basis.  And while I was at it I thought it would be remiss of me not to do a 'pure' Julian calendar, which may be useful for members of some Orthodox Christian churches.

The end result you can see below is full support for the Indian National calendar, currently from 0000-01-01 through to 9999-12-30.

Indian National 20 October

Indian National earlist date

Indian National latest date

Yes, I realise that the week numbers are wrong in the year 0, that's an existing bug in our ISO week number code for all years < 1 that I have to fix.

Could I ask all our friends in India to have a play with it and let me know if there are any glaring errors?  Just update trunk kdelibs and kdebase then run "plasmoidviewer calendar" or "plasmoidviewer digital-clock", go into the widget settings and change the Calendar to Indian National.  It passes the tests I have here, but they are not yet comprehensive.  

The other thing I need to ask is to confirm the month and weekday name transliterations I have used from the net are 'correct' (i.e. current best practice), and that the short forms I have invented are OK and not something rude :-)  Is there a standard set of 3 char abbreviations I should be using?

The month names I've used from Wikipedia along with my made-up abbreviations are:

  1. Chaitra  -  Cha
  2. Vaishākh  -  Vai
  3. Jyaishtha  -  Jya
  4. Āshādha  -  Āsh
  5. Shrāvana  -  Shr
  6. Bhādrapad  -  Bhā
  7. Āshwin  -  Āsw
  8. Kārtik  -  Kār
  9. Agrahayana  -  Agr
  10. Paush  -  Pau
  11. Māgh  -  Māg
  12. Phālgun  -  Phā

The weekday names I've used from somewhere are (starting from Monday):

  1. Somavãra  -  Som
  2. Mañgalvã  -  Mañ
  3. Budhavãra  -  Bud
  4. Guruvãra  -  Gur
  5. Sukravãra  -  Suk
  6. Sanivãra  -  San
  7. Raviãra  -  Rav

TIA!

So our supported list of calendars is now:

  • Gregorian
  • Hebrew
  • Hijri
  • Indian National
  • Jalali
  • Julian

Note that the 'pure' Gregorian won't yet be offered as a choice to users as I'm concerned about the possible confusion from seeing Gregorian twice in the list, and with inconsistencies arising with anything using the existing Gregorian or QDate stuff.  However, it is there for apps to use if they need to.

Now, I'm a strong believer in our translation and localisation being one of our greatest strengths and selling points, not only something that could see us 'winning' in markets that the big players just can't be bothered with, but also helping bring the benfits of computers and the net to people who might not otherwise be able to access them.  Providing as many local calendar systems as possible is part of that.  So how do we compare at the moment to the competition?

OSX 10.5 lets you choose any of the following:

  • Gregorian
  • Buddhist
  • Hebrew
  • Islamic
  • Islamic, Civil
  • Japanese

As the only OS to currently support the Buddist calendar, I suspect Steve Jobs was behind that feature :-)

Windows Vista and 7 has a real brain-dead scheme when it comes to Calendar Systems.  Want an English desktop and the Hijri or Hebrew calendar?  Sorry, no can do!  You have to choose Arabic or Hebrew as your language, then it lets you choose which calendar system to use.  It restricts what calendar(s) you are allowed to choose from based on first your language and second your country, which while good for choosing default values seems seriously restrictive for no good reason.  And their desktop 'Gadget' will only display the global calendar.  Fail.  Anyway, according to MSDN the supported calendars are:

  • Gregorian (6 different localised varieties)
  • Japanese Emperor Era
  • Taiwan calendar
  • Korean Tangun Era
  • Hijri (Arabic Lunar)
  • Thai
  • Hebrew (Lunar)
  • Um Al Qura (Arabic lunar) calendar

Actually, I'd better be careful with throwing the insults Microsofts way, because Gnome I'm sorry to say apparently gives you even less choice.  Far as I can tell, Gnome sets all your regional settings based on your chosen language and gives you no way to adjust any of the settings: date formats, number formats, calendar system, nothing.  You can manually edit the locale file but that's it.  So far so Gnome, that's just their way.  But I've tried poking around gnome.org and Googling to see what other calendar systems they support, but can't seem to find anything.  Reading the code of Glib's GDate and Gtk's gtkcalendar.c would suggest however that they only support Gregorian as the system calendar!  That can't be right, surely?  Can anyone set me right?

So it looks a real mixed bag of supported systems with Windows having the lead, but it's something I'm determined we will lead in by KDE 4.6.

Next up is the Bahá'í calendar and possibly the Ethiopian calendar before the 4.4 feature freeze, then some bug fixing on the Jalali and Hebrew calendars and a new test suite for all the calendar systems.  Then for 4.5 I hope to get around to the astronomical calculations required for lunar based calendars like the Chinese, Islamic religious, Indian religious, etc.  I think I'll need to do some astronomy night classes before then :-)

If you do have a local calendar system that you use daily and would like supported, and it doesn't rely on astronomical calculations (new moon, sunset, etc) then drop me a line and I'll see what I can do before 4.4.

Syndicate content