//----------------------------------------------------------------------------80
{
Author: Michael James Biggs
Initial Date: 2022-10-31
Version: 1.0
Version: 1.1 2022-10-31
- added ability to distinguish astronomical seasons in Northern and
Southern hemispheres using functions:
funcGetSeasonAstroNorth
funcGetSeasonAstroSouth
- various minor tweaks
Version: 1.2 2022-11-01
- replaced use of UpperCase by WideUpperCase
- replaced use of LowerCase by WideLowerCase
- replaced PublicCatalog.EnumCategoryNamed('Miscellaneous', ACategory)
by PublicCatalog.EnumCategory(KeywordsGUID, ACategory, False)
- added function funcFormatISODateTimeString
- updated astronomical functions to use ISO DateTime string conversions
funcGetSeasonAstroNorth
funcGetSeasonAstroSouth
- appended astropixels GMT data set to end of script
- updated spreadsheet helper to include astropixels GMT data set
- various minor tweaks
Version: 1.3 2022-11-02
- updated functions to use DateTimeToISODateString
funcGetSeasonAstroNorth
funcGetSeasonAstroSouth
funcGetSeasonMeteoNorth
funcGetSeasonMeteoSouth
- various minor tweaks
Version: 1.4 2022-11-02
- changed AWStrListReportText from TStringList to TTntStringList
- changed ChangeFileExt to WideChangeFileExt
- changed DirectoryExists to WideDirectoryExists
- changed CreateDir to WideForceDirectories
- for AWStrListReportText, enclosed file names in double quotes to allow
for file names containing commas
- various minor tweaks
Version: 1.5 2022-11-02
- improved formatting of csv lines for AWStrListReportText
csv lines are now constructed by first adding items to a line
TTntStringList then using member identifier '.CommaText' to add that
list as a single csv line to AWStrListReportText
(using '.CommaText' automatically escapes items containing spaces
and commas by enclosing them in double quotes)
Version: 1.6 2022-11-03
- updated AWStrReportPath to use default windows document path if no user
path specified
- renamed cATextEditor as cAEditor
- set cAScriptReportPath to null, to use default windows document path
- set cAEditor to null, to use default editor associated with '.csv' files
- moved astropixels table to separate document
- various minor tweaks
Version: 1.7 2022-11-04
- added Acknowledgements section in script header
- replaced astropixels time and date data with NASA GISS data
- updated spreadsheet helper to use NASA GISS data
- various minor tweaks
Version: 1.8 2022-11-04
- changed AWStrListReportLine from TTntStringList to TStringList
- changed AWStrListReportText from TTntStringList to TStringList
- added UTF-8 encoding to csv lines using UTF8Encode
Name: Sort Into Season Collections.psc
Full Name: PSU_Sort__for_Selected_Images_Collection_or_Portfolio__Files_into_
Seasons__Astronomical_and_Meteorological__LABEL.psc
Description: A Photo Supreme script to sort items by season for selected
images, collections or portfolio. Sorted items are added to
season collections. Optionally, each item may be updated with
a season catalog label (keyword) in the KeywordsGUID category,
(ie 'Miscellaneous'), if not already present.
Usage: Download script
Use a text editor to edit downloaded script
Change settings as needed (see below) and save
Place script in Photo Supreme script folder:
...\IDimager Products\Photo Supreme x64\Resources\Scripts
Open Photo Supreme
Under Portfolios tab, select images, a Collection or a Portfolio
Open Scripter (Hamburger Menu->Tools->Scripter)
Load downloaded/edited script (Open->select script->Open)
Use Scripter to edit script settings as needed (see below)
Click Run
Seasons: Astronomical seasons:
Edit script to remove or replace time and date data as needed;
search script for 'TIME AND DATE DATA SET'
Follow instructions in 'HELPER' spreadsheet to get data in
suitable format then copy and paste as necessary.
Edit script to change constant values as needed:
cASeasonAstroSort sort astronomical [0=no, 1=yes]
cASeasonAstroDataSet data set description
Meteorological seasons:
Edit script to change constant values as needed:
cASeasonMeteoSort sort meteorological [0=no, 1=yes]
Hemisphere:
Edit script to change constant value as needed:
cASeasonHemisphere 'Northern' or 'Southern'
Season label:
Edit script to change constant value as needed:
cASeasonAddLabel add season label [0=no, 1=yes]
Settings: Edit the script to change the following constant values as needed:
cASaveReport save report [0=no, 1=yes]
cAScriptReportDir report directory
cAScriptReportName report file name
cAScriptReportPath report folder path
cAShowDialog show dialog [0=no, 1=yes]
cAEditor editor path to open report '.csv' file
Warning: If cASeasonAddLabel is set to 1, original files will be modified
unless 'auto-sync' checkbox is unchecked.
(Preferences->Synchronize Settings->Automatically write out...)
PSU: Tested with: IDimager Photo Supreme [build 5.6.0.3432 (64 bit)]
IDimager Photo Supreme [build 6.7.2.4229 (64 bit)]
IDimager Photo Supreme [build 7.4.1.4604 (64 bit)]
System: Tested with: Microsoft Windows 10 Home (x64)
[Version 21H2 Build 19044.2130]
Disclaimer: Use at own risk. Recommend backing up catalog before use.
Acknowledgements: Thanks to IDimager for feedback, code advice
and encouragement.
Reference: Based on scripts and code snippets authored by IDimager
(and others), either stored in the Photo Supreme Resource
Repository or presented in the Photo Supreme User-To-User Forum.
}
const
cASaveReport = 1; // [0=no, 1=yes]
cAScriptName = 'Sort Into Season Collections.psc';
cAScriptFullName = 'Sort__for_Selected_Images_Collection_or_Portfolio__' +
'Files_into_Seasons__Astronomical_and_Meteorological__' +
'LABEL.psc';
cAScriptReportDir = 'Photo_Supreme_Script_Report';
cAScriptReportName = 'script_report.csv';
// specified folder path must terminate in backslash '\', for example:
// cAScriptReportPath = 'C:\Users\<username>\Documents\';
// assign null string '' to use default windows document path
cAScriptReportPath = '';
cASeasonAddLabel = 0; // [0=no, 1=yes]
cASeasonAstroSort = 1; // [0=no, 1=yes]
cASeasonAstroDataSet = 'NASA GISS (GMT)';
cASeasonHemisphere = 'Northern';
cASeasonMeteoSort = 1; // [0=no, 1=yes]
cAShowDialog = 1; // [0=no, 1=yes]
// specified editor must use full path, for example:
// cAEditor = 'C:\Program Files\Notepad++\notepad++.exe';
// assign null string '' to use default editor associated with '.csv' files,
// ie Excel/LibreOffice/etc
cAEditor = '';
var
gATStrListCatItemGUID: TTntStringList; // global var
gATStrListCatItemParentGUID: TTntStringList; // global var
//gACatItemsArray: TidElement; // global var // FOR ARRAY METHOD
//--------------------------------------------------------------------------80
function funcChangeToTitleCase(AWStrText: WideString): WideString;
begin
result := WideUppercase(LeftStr(AWStrText, 1)) +
WideLowerCase(RightStr(AWStrText, Length(AWStrText) - 1));
end;
//--------------------------------------------------------------------------80
procedure procLabelImgItem(AImage: TImageItem; ALabel: WideString);
// KeywordsGUID = '{6B36224B-1405-47A0-8430-573229C8CCB9}'
// is equivalent to 'Miscellaneous' category
var
ACatItem: TCatalogItem;
AProp: TCatalogItemProp;
begin
ACatItem := TCatalogItem.Create(nil);
AProp := TCatalogItemProp.Create(nil);
// get main version
if PublicCatalog.FindImageCombined (AImage, ACatItem, True, vptNone) then
begin
// check for existing catalog prop with name ALabel
// (FindPropByName: assigns value to AProp as first matching prop found
// from non ordered list of props; this means prop ALabel added to
// catalog item may be from KeywordsGUID category, but equally may be
// from some other category)
if not PublicCatalog.FindPropByName (ALabel, AProp, '', True) then
begin
// match not found so create one in KeywordsGUID category
AProp.GUID := NewGUID; // give a unique ID
AProp.PropName := ALabel;
PublicCatalog.StorePropToDatabase (AProp, KeywordsGUID, False);
end;
// assign prop, (match pre-existing or newly created), to catalog item
PublicCatalog.AddPropToItem (ACatItem, AProp, False, False);
end;
AProp.Free;
ACatItem.Free;
end;
//--------------------------------------------------------------------------80
procedure procLabelImgItemKeywords(AImage: TImageItem; ALabel: WideString);
// KeywordsGUID = '{6B36224B-1405-47A0-8430-573229C8CCB9}'
// is equivalent to 'Miscellaneous' category
var
ACatItem: TCatalogItem;
AProp: TCatalogItemProp;
ACategory: TCatalogPropCategory;
begin
ACatItem := TCatalogItem.Create(nil);
AProp := TCatalogItemProp.Create(nil);
AProps := TCatalogItemProps.Create(TCatalogItemProp, '');
ACategory := TCatalogPropCategory.Create(nil);
// get main version
if PublicCatalog.FindImageCombined(AImage, ACatItem, True, vptNone) then
begin
// if KeywordsGUID category exists
if PublicCatalog.EnumCategory(KeywordsGUID, ACategory, False) then
begin
// check for existing prop with name ALabel in KeywordsGUID category
if not PublicCatalog.EnumPropName(ACategory.GUID, ALabel, AProp, False) then
begin
// no prop found so create new one in KeywordsGUID category
AProp.GUID := NewGUID; // give a unique ID
AProp.PropName := ALabel;
PublicCatalog.StorePropToDatabase(AProp, KeywordsGUID, False);
end;
// assign prop from KeywordsGUID category
PublicCatalog.AddPropToItem(ACatItem, AProp, False, False);
end;
// else do nothing
end;
ACatItem.Free;
AProp.Free;
ACategory.Free;
end;
//--------------------------------------------------------------------------80
procedure procDeleteTStrListDupCatItem;
var
i: Integer;
begin
for i := gATStrListCatItemGUID.Count - 1 downto 1 do // global var
begin
if gATStrListCatItemGUID.IndexOf(gATStrListCatItemGUID.Strings[i]) <> i then // global var
begin
gATStrListCatItemGUID.Delete(i); // global var
gATStrListCatItemParentGUID.Delete(i); // global var
end;
end;
end;
//--------------------------------------------------------------------------80
function funcAddArrayElemCatItem(AArray: TidElement;
ACatItemGUID: WideString;
ACatItemParentGUID: WideString): TidElement;
begin
result := AArray.Elements.Add;
result.Prop['CatItemGUID'] := ACatItemGUID;
result.Prop['CatItemParentGUID'] := ACatItemParentGUID;
end;
//--------------------------------------------------------------------------80
function funcCreateCollection(ACGUIDParent: WideString;
ACName: WideString;
ACDescription: WideString): TImageCollection;
var
AImageColls: TImageCollections;
AImageColl: TImageCollection;
begin
// load AImageColls with all current collection names
// for parent ACGUIDParent
AImageColls := TImageCollections.Create(TImageCollection, '');
PublicCatalog.EnumCollectionsForParent(ACGUIDParent,
AImageColls);
// check if collection already exists
AImageColl := AImageColls.FindNamed(ACName);
if AImageColl = nil then
begin
// create collection if doesn't already exist
AImageColl := TImageCollection.Create(nil);
AImageColl.CollectionName := ACName;
AImageColl.CollectionDescription := ACDescription;
PublicCatalog.StoreCollectionToParentSimple(ACGUIDParent,
AImageColl);
end;
Result := AImageColl;
end;
//--------------------------------------------------------------------------80
procedure procGetCollAllCatItems(AColl: TImageCollection);
// (RECURSIVE)
var
i: Integer;
ACatItems: TCatalogItems;
ASubColls: TImageCollections;
begin
// get catalogue items
ACatItems := TCatalogItems.Create(TCatalogItem, '');
PublicCatalog.EnumItemsInCollection(AColl, ACatItems);
if ACatItems.Count > 0 then
begin
for i := 0 to ACatItems.Count - 1 do
begin
//funcAddArrayElemCatItem(gACatItemsArray, ACatItems.Items[i].GUID, AColl.GUID); // CALL FUNC // global var // FOR ARRAY METHOD
gATStrListCatItemGUID.Add(ACatItems.Items[i].GUID); // global var
gATStrListCatItemParentGUID.Add(AColl.GUID); // global var
end;
end;
ACatItems.Free;
// process sub collections
if PublicCatalog.CollectionHasCollections(AColl.GUID) then
begin
ASubColls := TImageCollections.Create(TImageCollection, '');
PublicCatalog.EnumCollectionCollections(AColl, ASubColls);
if ASubColls.Count > 0 then
begin
for i := 0 to ASubColls.Count - 1 do
procGetCollAllCatItems(ASubColls.Items[i]); // CALL PROC
end;
ASubColls.Free;
end;
end;
//--------------------------------------------------------------------------80
procedure procGetCollsAllCatItems(AColls: TImageCollections);
// (RECURSIVE)
var
i, j: Integer;
ACatItems: TCatalogItems;
ASubColls: TImageCollections;
begin
if AColls.Count > 0 then
begin
for i := 0 to AColls.Count - 1 do
begin
// count catalogue items in sub collection
ACatItems := TCatalogItems.Create(TCatalogItem, '');
PublicCatalog.EnumItemsInCollection(AColls.Items[i], ACatItems);
if ACatItems.Count > 0 then
begin
for j := 0 to ACatItems.Count - 1 do
begin
//funcAddArrayElemCatItem(gACatItemsArray, ACatItems.Items[j].GUID, AColls.Items[i].GUID); // CALL FUNC // global var // FOR ARRAY METHOD
gATStrListCatItemGUID.Add(ACatItems.Items[j].GUID); // global var
gATStrListCatItemParentGUID.Add(AColls.Items[i].GUID); // global var
end;
end;
ACatItems.Free;
// process sub collections in sub collection
if PublicCatalog.CollectionHasCollections(AColls.Items[i].GUID) then
begin
ASubColls := TImageCollections.Create(TImageCollection, '');
PublicCatalog.EnumCollectionCollections(AColls.Items[i], ASubColls);
procGetCollsAllCatItems(ASubColls); // CALL PROC
ASubColls.Free;
end;
end;
end;
end;
//--------------------------------------------------------------------------80
procedure procCreatePortfolioGUID(APortfolioGUID: WideString;
APortfolioName: WideString;
APortfolioDescription: WideString);
var
APortfolio: TImageModel;
AGallery: TImageGallery;
begin
// create portfolio (with gallery) if doesn't already exist
APortfolio := TImageModel.Create(nil);
if not PublicCatalog.EnumModel(APortfolioGUID, APortfolio) then
begin
APortfolio := TImageModel.Create(nil);
try
APortfolio.ModelName := APortfolioName;
APortfolio.Description := APortfolioDescription;
APortfolio.Galleries.Clear;
AGallery := APortfolio.Galleries.Add as TImageGallery;
AGallery.GalleryName := APortfolio.ModelName;
AGallery.Collections.Clear;
PublicCatalog.StoreModelToDatabase(APortfolio);
finally
AGallery.Free;
APortfolio.Free;
end;
end;
end;
//--------------------------------------------------------------------------80
procedure procCreatePortfolioNamed(APortfolioName: WideString;
APortfolioDescription: WideString);
var
APortfolio: TImageModel;
AGallery: TImageGallery;
begin
// create portfolio (with gallery) if doesn't already exist
APortfolio := TImageModel.Create(nil);
if not PublicCatalog.EnumModelNamed(APortfolioName, APortfolio) then
begin
APortfolio := TImageModel.Create(nil);
try
APortfolio.ModelName := APortfolioName;
APortfolio.Description := APortfolioDescription;
APortfolio.Galleries.Clear;
AGallery := APortfolio.Galleries.Add as TImageGallery;
AGallery.GalleryName := APortfolio.ModelName;
AGallery.Collections.Clear;
PublicCatalog.StoreModelToDatabase(APortfolio);
finally
AGallery.Free;
APortfolio.Free;
end;
end;
end;
//--------------------------------------------------------------------------80
function funcAddArrayElem(AArray: TidElement;
AYear: WideString;
AMarE, AJunS, ASepE, ADecS: WideString): TidElement;
begin
result := AArray.Elements.Add;
result.Prop['Year'] := AYear;
result.Prop['MarE'] := AMarE; // March Equinox
result.Prop['JunS'] := AJunS; // June Solstice
result.Prop['SepE'] := ASepE; // September Equinox
result.Prop['DecS'] := ADecS; // December Solstice
end;
//--------------------------------------------------------------------------80
function funcInitArray: TidElement;
var
AElem: TidElement;
begin
result := TidElement.Create(nil);
//**************************************************************************
//**************************************************************************
//*************************************************** TIME AND DATE DATA SET
//**************************************************************************
//**************************************************************************
// website: NASA Goddard Institute for Space Studies
// year: 2022
// title: Time and Date of Vernal Equinox: 1800 to 2100
// accessed: 2022-11-04
// url: https://data.giss.nasa.gov/modelE/ar5plots/srvernal.html
funcAddArrayElem( result, '1800', '1800-03-20 19:30', '1800-06-21 17:15', '1800-09-23 06:48', '1800-12-21 23:34' ); // CALL FUNC
funcAddArrayElem( result, '1801', '1801-03-21 01:19', '1801-06-21 23:03', '1801-09-23 12:36', '1801-12-22 05:24' ); // CALL FUNC
funcAddArrayElem( result, '1802', '1802-03-21 07:08', '1802-06-22 04:51', '1802-09-23 18:25', '1802-12-22 11:14' ); // CALL FUNC
funcAddArrayElem( result, '1803', '1803-03-21 12:58', '1803-06-22 10:39', '1803-09-24 00:14', '1803-12-22 17:04' ); // CALL FUNC
funcAddArrayElem( result, '1804', '1804-03-20 18:47', '1804-06-21 16:28', '1804-09-23 06:03', '1804-12-21 22:54' ); // CALL FUNC
funcAddArrayElem( result, '1805', '1805-03-21 00:36', '1805-06-21 22:16', '1805-09-23 11:52', '1805-12-22 04:43' ); // CALL FUNC
funcAddArrayElem( result, '1806', '1806-03-21 06:25', '1806-06-22 04:04', '1806-09-23 17:40', '1806-12-22 10:33' ); // CALL FUNC
funcAddArrayElem( result, '1807', '1807-03-21 12:14', '1807-06-22 09:52', '1807-09-23 23:29', '1807-12-22 16:23' ); // CALL FUNC
funcAddArrayElem( result, '1808', '1808-03-20 18:04', '1808-06-21 15:40', '1808-09-23 05:18', '1808-12-21 22:13' ); // CALL FUNC
funcAddArrayElem( result, '1809', '1809-03-20 23:53', '1809-06-21 21:28', '1809-09-23 11:07', '1809-12-22 04:03' ); // CALL FUNC
funcAddArrayElem( result, '1810', '1810-03-21 05:42', '1810-06-22 03:16', '1810-09-23 16:56', '1810-12-22 09:52' ); // CALL FUNC
funcAddArrayElem( result, '1811', '1811-03-21 11:31', '1811-06-22 09:05', '1811-09-23 22:44', '1811-12-22 15:42' ); // CALL FUNC
funcAddArrayElem( result, '1812', '1812-03-20 17:20', '1812-06-21 14:53', '1812-09-23 04:33', '1812-12-21 21:32' ); // CALL FUNC
funcAddArrayElem( result, '1813', '1813-03-20 23:10', '1813-06-21 20:41', '1813-09-23 10:22', '1813-12-22 03:22' ); // CALL FUNC
funcAddArrayElem( result, '1814', '1814-03-21 04:59', '1814-06-22 02:29', '1814-09-23 16:11', '1814-12-22 09:11' ); // CALL FUNC
funcAddArrayElem( result, '1815', '1815-03-21 10:48', '1815-06-22 08:17', '1815-09-23 21:59', '1815-12-22 15:01' ); // CALL FUNC
funcAddArrayElem( result, '1816', '1816-03-20 16:37', '1816-06-21 14:05', '1816-09-23 03:48', '1816-12-21 20:51' ); // CALL FUNC
funcAddArrayElem( result, '1817', '1817-03-20 22:26', '1817-06-21 19:54', '1817-09-23 09:37', '1817-12-22 02:41' ); // CALL FUNC
funcAddArrayElem( result, '1818', '1818-03-21 04:16', '1818-06-22 01:42', '1818-09-23 15:26', '1818-12-22 08:31' ); // CALL FUNC
funcAddArrayElem( result, '1819', '1819-03-21 10:05', '1819-06-22 07:30', '1819-09-23 21:15', '1819-12-22 14:20' ); // CALL FUNC
funcAddArrayElem( result, '1820', '1820-03-20 15:54', '1820-06-21 13:18', '1820-09-23 03:03', '1820-12-21 20:10' ); // CALL FUNC
funcAddArrayElem( result, '1821', '1821-03-20 21:43', '1821-06-21 19:06', '1821-09-23 08:52', '1821-12-22 02:00' ); // CALL FUNC
funcAddArrayElem( result, '1822', '1822-03-21 03:32', '1822-06-22 00:54', '1822-09-23 14:41', '1822-12-22 07:50' ); // CALL FUNC
funcAddArrayElem( result, '1823', '1823-03-21 09:22', '1823-06-22 06:43', '1823-09-23 20:30', '1823-12-22 13:40' ); // CALL FUNC
funcAddArrayElem( result, '1824', '1824-03-20 15:11', '1824-06-21 12:31', '1824-09-23 02:19', '1824-12-21 19:29' ); // CALL FUNC
funcAddArrayElem( result, '1825', '1825-03-20 21:00', '1825-06-21 18:19', '1825-09-23 08:07', '1825-12-22 01:19' ); // CALL FUNC
funcAddArrayElem( result, '1826', '1826-03-21 02:49', '1826-06-22 00:07', '1826-09-23 13:56', '1826-12-22 07:09' ); // CALL FUNC
funcAddArrayElem( result, '1827', '1827-03-21 08:38', '1827-06-22 05:55', '1827-09-23 19:45', '1827-12-22 12:59' ); // CALL FUNC
funcAddArrayElem( result, '1828', '1828-03-20 14:28', '1828-06-21 11:43', '1828-09-23 01:34', '1828-12-21 18:48' ); // CALL FUNC
funcAddArrayElem( result, '1829', '1829-03-20 20:17', '1829-06-21 17:31', '1829-09-23 07:22', '1829-12-22 00:38' ); // CALL FUNC
funcAddArrayElem( result, '1830', '1830-03-21 02:06', '1830-06-21 23:20', '1830-09-23 13:11', '1830-12-22 06:28' ); // CALL FUNC
funcAddArrayElem( result, '1831', '1831-03-21 07:55', '1831-06-22 05:08', '1831-09-23 19:00', '1831-12-22 12:18' ); // CALL FUNC
funcAddArrayElem( result, '1832', '1832-03-20 13:44', '1832-06-21 10:56', '1832-09-23 00:49', '1832-12-21 18:08' ); // CALL FUNC
funcAddArrayElem( result, '1833', '1833-03-20 19:34', '1833-06-21 16:44', '1833-09-23 06:38', '1833-12-21 23:57' ); // CALL FUNC
funcAddArrayElem( result, '1834', '1834-03-21 01:23', '1834-06-21 22:32', '1834-09-23 12:26', '1834-12-22 05:47' ); // CALL FUNC
funcAddArrayElem( result, '1835', '1835-03-21 07:12', '1835-06-22 04:20', '1835-09-23 18:15', '1835-12-22 11:37' ); // CALL FUNC
funcAddArrayElem( result, '1836', '1836-03-20 13:01', '1836-06-21 10:09', '1836-09-23 00:04', '1836-12-21 17:27' ); // CALL FUNC
funcAddArrayElem( result, '1837', '1837-03-20 18:50', '1837-06-21 15:57', '1837-09-23 05:53', '1837-12-21 23:17' ); // CALL FUNC
funcAddArrayElem( result, '1838', '1838-03-21 00:40', '1838-06-21 21:45', '1838-09-23 11:41', '1838-12-22 05:06' ); // CALL FUNC
funcAddArrayElem( result, '1839', '1839-03-21 06:29', '1839-06-22 03:33', '1839-09-23 17:30', '1839-12-22 10:56' ); // CALL FUNC
funcAddArrayElem( result, '1840', '1840-03-20 12:18', '1840-06-21 09:21', '1840-09-22 23:19', '1840-12-21 16:46' ); // CALL FUNC
funcAddArrayElem( result, '1841', '1841-03-20 18:07', '1841-06-21 15:09', '1841-09-23 05:08', '1841-12-21 22:36' ); // CALL FUNC
funcAddArrayElem( result, '1842', '1842-03-20 23:56', '1842-06-21 20:57', '1842-09-23 10:56', '1842-12-22 04:25' ); // CALL FUNC
funcAddArrayElem( result, '1843', '1843-03-21 05:46', '1843-06-22 02:46', '1843-09-23 16:45', '1843-12-22 10:15' ); // CALL FUNC
funcAddArrayElem( result, '1844', '1844-03-20 11:35', '1844-06-21 08:34', '1844-09-22 22:34', '1844-12-21 16:05' ); // CALL FUNC
funcAddArrayElem( result, '1845', '1845-03-20 17:24', '1845-06-21 14:22', '1845-09-23 04:23', '1845-12-21 21:55' ); // CALL FUNC
funcAddArrayElem( result, '1846', '1846-03-20 23:13', '1846-06-21 20:10', '1846-09-23 10:12', '1846-12-22 03:45' ); // CALL FUNC
funcAddArrayElem( result, '1847', '1847-03-21 05:02', '1847-06-22 01:58', '1847-09-23 16:00', '1847-12-22 09:34' ); // CALL FUNC
funcAddArrayElem( result, '1848', '1848-03-20 10:52', '1848-06-21 07:46', '1848-09-22 21:49', '1848-12-21 15:24' ); // CALL FUNC
funcAddArrayElem( result, '1849', '1849-03-20 16:41', '1849-06-21 13:35', '1849-09-23 03:38', '1849-12-21 21:14' ); // CALL FUNC
funcAddArrayElem( result, '1850', '1850-03-20 22:30', '1850-06-21 19:23', '1850-09-23 09:27', '1850-12-22 03:04' ); // CALL FUNC
funcAddArrayElem( result, '1851', '1851-03-21 04:19', '1851-06-22 01:11', '1851-09-23 15:15', '1851-12-22 08:53' ); // CALL FUNC
funcAddArrayElem( result, '1852', '1852-03-20 10:08', '1852-06-21 06:59', '1852-09-22 21:04', '1852-12-21 14:43' ); // CALL FUNC
funcAddArrayElem( result, '1853', '1853-03-20 15:58', '1853-06-21 12:47', '1853-09-23 02:53', '1853-12-21 20:33' ); // CALL FUNC
funcAddArrayElem( result, '1854', '1854-03-20 21:47', '1854-06-21 18:35', '1854-09-23 08:42', '1854-12-22 02:23' ); // CALL FUNC
funcAddArrayElem( result, '1855', '1855-03-21 03:36', '1855-06-22 00:23', '1855-09-23 14:30', '1855-12-22 08:13' ); // CALL FUNC
funcAddArrayElem( result, '1856', '1856-03-20 09:25', '1856-06-21 06:12', '1856-09-22 20:19', '1856-12-21 14:02' ); // CALL FUNC
funcAddArrayElem( result, '1857', '1857-03-20 15:14', '1857-06-21 12:00', '1857-09-23 02:08', '1857-12-21 19:52' ); // CALL FUNC
funcAddArrayElem( result, '1858', '1858-03-20 21:04', '1858-06-21 17:48', '1858-09-23 07:57', '1858-12-22 01:42' ); // CALL FUNC
funcAddArrayElem( result, '1859', '1859-03-21 02:53', '1859-06-21 23:36', '1859-09-23 13:46', '1859-12-22 07:32' ); // CALL FUNC
funcAddArrayElem( result, '1860', '1860-03-20 08:42', '1860-06-21 05:24', '1860-09-22 19:34', '1860-12-21 13:21' ); // CALL FUNC
funcAddArrayElem( result, '1861', '1861-03-20 14:31', '1861-06-21 11:12', '1861-09-23 01:23', '1861-12-21 19:11' ); // CALL FUNC
funcAddArrayElem( result, '1862', '1862-03-20 20:20', '1862-06-21 17:00', '1862-09-23 07:12', '1862-12-22 01:01' ); // CALL FUNC
funcAddArrayElem( result, '1863', '1863-03-21 02:10', '1863-06-21 22:49', '1863-09-23 13:01', '1863-12-22 06:51' ); // CALL FUNC
funcAddArrayElem( result, '1864', '1864-03-20 07:59', '1864-06-21 04:37', '1864-09-22 18:49', '1864-12-21 12:41' ); // CALL FUNC
funcAddArrayElem( result, '1865', '1865-03-20 13:48', '1865-06-21 10:25', '1865-09-23 00:38', '1865-12-21 18:30' ); // CALL FUNC
funcAddArrayElem( result, '1866', '1866-03-20 19:37', '1866-06-21 16:13', '1866-09-23 06:27', '1866-12-22 00:20' ); // CALL FUNC
funcAddArrayElem( result, '1867', '1867-03-21 01:26', '1867-06-21 22:01', '1867-09-23 12:16', '1867-12-22 06:10' ); // CALL FUNC
funcAddArrayElem( result, '1868', '1868-03-20 07:16', '1868-06-21 03:49', '1868-09-22 18:04', '1868-12-21 12:00' ); // CALL FUNC
funcAddArrayElem( result, '1869', '1869-03-20 13:05', '1869-06-21 09:38', '1869-09-22 23:53', '1869-12-21 17:49' ); // CALL FUNC
funcAddArrayElem( result, '1870', '1870-03-20 18:54', '1870-06-21 15:26', '1870-09-23 05:42', '1870-12-21 23:39' ); // CALL FUNC
funcAddArrayElem( result, '1871', '1871-03-21 00:43', '1871-06-21 21:14', '1871-09-23 11:31', '1871-12-22 05:29' ); // CALL FUNC
funcAddArrayElem( result, '1872', '1872-03-20 06:32', '1872-06-21 03:02', '1872-09-22 17:19', '1872-12-21 11:19' ); // CALL FUNC
funcAddArrayElem( result, '1873', '1873-03-20 12:22', '1873-06-21 08:50', '1873-09-22 23:08', '1873-12-21 17:08' ); // CALL FUNC
funcAddArrayElem( result, '1874', '1874-03-20 18:11', '1874-06-21 14:38', '1874-09-23 04:57', '1874-12-21 22:58' ); // CALL FUNC
funcAddArrayElem( result, '1875', '1875-03-21 00:00', '1875-06-21 20:26', '1875-09-23 10:46', '1875-12-22 04:48' ); // CALL FUNC
funcAddArrayElem( result, '1876', '1876-03-20 05:49', '1876-06-21 02:15', '1876-09-22 16:34', '1876-12-21 10:38' ); // CALL FUNC
funcAddArrayElem( result, '1877', '1877-03-20 11:38', '1877-06-21 08:03', '1877-09-22 22:23', '1877-12-21 16:28' ); // CALL FUNC
funcAddArrayElem( result, '1878', '1878-03-20 17:28', '1878-06-21 13:51', '1878-09-23 04:12', '1878-12-21 22:17' ); // CALL FUNC
funcAddArrayElem( result, '1879', '1879-03-20 23:17', '1879-06-21 19:39', '1879-09-23 10:01', '1879-12-22 04:07' ); // CALL FUNC
funcAddArrayElem( result, '1880', '1880-03-20 05:06', '1880-06-21 01:27', '1880-09-22 15:49', '1880-12-21 09:57' ); // CALL FUNC
funcAddArrayElem( result, '1881', '1881-03-20 10:55', '1881-06-21 07:15', '1881-09-22 21:38', '1881-12-21 15:47' ); // CALL FUNC
funcAddArrayElem( result, '1882', '1882-03-20 16:44', '1882-06-21 13:03', '1882-09-23 03:27', '1882-12-21 21:36' ); // CALL FUNC
funcAddArrayElem( result, '1883', '1883-03-20 22:34', '1883-06-21 18:52', '1883-09-23 09:16', '1883-12-22 03:26' ); // CALL FUNC
funcAddArrayElem( result, '1884', '1884-03-20 04:23', '1884-06-21 00:40', '1884-09-22 15:04', '1884-12-21 09:16' ); // CALL FUNC
funcAddArrayElem( result, '1885', '1885-03-20 10:12', '1885-06-21 06:28', '1885-09-22 20:53', '1885-12-21 15:06' ); // CALL FUNC
funcAddArrayElem( result, '1886', '1886-03-20 16:01', '1886-06-21 12:16', '1886-09-23 02:42', '1886-12-21 20:55' ); // CALL FUNC
funcAddArrayElem( result, '1887', '1887-03-20 21:50', '1887-06-21 18:04', '1887-09-23 08:31', '1887-12-22 02:45' ); // CALL FUNC
funcAddArrayElem( result, '1888', '1888-03-20 03:40', '1888-06-20 23:52', '1888-09-22 14:19', '1888-12-21 08:35' ); // CALL FUNC
funcAddArrayElem( result, '1889', '1889-03-20 09:29', '1889-06-21 05:40', '1889-09-22 20:08', '1889-12-21 14:25' ); // CALL FUNC
funcAddArrayElem( result, '1890', '1890-03-20 15:18', '1890-06-21 11:29', '1890-09-23 01:57', '1890-12-21 20:14' ); // CALL FUNC
funcAddArrayElem( result, '1891', '1891-03-20 21:07', '1891-06-21 17:17', '1891-09-23 07:46', '1891-12-22 02:04' ); // CALL FUNC
funcAddArrayElem( result, '1892', '1892-03-20 02:56', '1892-06-20 23:05', '1892-09-22 13:34', '1892-12-21 07:54' ); // CALL FUNC
funcAddArrayElem( result, '1893', '1893-03-20 08:46', '1893-06-21 04:53', '1893-09-22 19:23', '1893-12-21 13:44' ); // CALL FUNC
funcAddArrayElem( result, '1894', '1894-03-20 14:35', '1894-06-21 10:41', '1894-09-23 01:12', '1894-12-21 19:34' ); // CALL FUNC
funcAddArrayElem( result, '1895', '1895-03-20 20:24', '1895-06-21 16:29', '1895-09-23 07:01', '1895-12-22 01:23' ); // CALL FUNC
funcAddArrayElem( result, '1896', '1896-03-20 02:13', '1896-06-20 22:17', '1896-09-22 12:49', '1896-12-21 07:13' ); // CALL FUNC
funcAddArrayElem( result, '1897', '1897-03-20 08:02', '1897-06-21 04:06', '1897-09-22 18:38', '1897-12-21 13:03' ); // CALL FUNC
funcAddArrayElem( result, '1898', '1898-03-20 13:52', '1898-06-21 09:54', '1898-09-23 00:27', '1898-12-21 18:53' ); // CALL FUNC
funcAddArrayElem( result, '1899', '1899-03-20 19:41', '1899-06-21 15:42', '1899-09-23 06:16', '1899-12-22 00:42' ); // CALL FUNC
funcAddArrayElem( result, '1900', '1900-03-21 01:30', '1900-06-21 21:30', '1900-09-23 12:04', '1900-12-22 06:32' ); // CALL FUNC
funcAddArrayElem( result, '1901', '1901-03-21 07:19', '1901-06-22 03:18', '1901-09-23 17:53', '1901-12-22 12:22' ); // CALL FUNC
funcAddArrayElem( result, '1902', '1902-03-21 13:08', '1902-06-22 09:06', '1902-09-23 23:42', '1902-12-22 18:12' ); // CALL FUNC
funcAddArrayElem( result, '1903', '1903-03-21 18:58', '1903-06-22 14:54', '1903-09-24 05:31', '1903-12-23 00:01' ); // CALL FUNC
funcAddArrayElem( result, '1904', '1904-03-21 00:47', '1904-06-21 20:43', '1904-09-23 11:19', '1904-12-22 05:51' ); // CALL FUNC
funcAddArrayElem( result, '1905', '1905-03-21 06:36', '1905-06-22 02:31', '1905-09-23 17:08', '1905-12-22 11:41' ); // CALL FUNC
funcAddArrayElem( result, '1906', '1906-03-21 12:25', '1906-06-22 08:19', '1906-09-23 22:57', '1906-12-22 17:31' ); // CALL FUNC
funcAddArrayElem( result, '1907', '1907-03-21 18:14', '1907-06-22 14:07', '1907-09-24 04:46', '1907-12-22 23:20' ); // CALL FUNC
funcAddArrayElem( result, '1908', '1908-03-21 00:04', '1908-06-21 19:55', '1908-09-23 10:34', '1908-12-22 05:10' ); // CALL FUNC
funcAddArrayElem( result, '1909', '1909-03-21 05:53', '1909-06-22 01:43', '1909-09-23 16:23', '1909-12-22 11:00' ); // CALL FUNC
funcAddArrayElem( result, '1910', '1910-03-21 11:42', '1910-06-22 07:31', '1910-09-23 22:12', '1910-12-22 16:50' ); // CALL FUNC
funcAddArrayElem( result, '1911', '1911-03-21 17:31', '1911-06-22 13:20', '1911-09-24 04:01', '1911-12-22 22:39' ); // CALL FUNC
funcAddArrayElem( result, '1912', '1912-03-20 23:20', '1912-06-21 19:08', '1912-09-23 09:49', '1912-12-22 04:29' ); // CALL FUNC
funcAddArrayElem( result, '1913', '1913-03-21 05:10', '1913-06-22 00:56', '1913-09-23 15:38', '1913-12-22 10:19' ); // CALL FUNC
funcAddArrayElem( result, '1914', '1914-03-21 10:59', '1914-06-22 06:44', '1914-09-23 21:27', '1914-12-22 16:09' ); // CALL FUNC
funcAddArrayElem( result, '1915', '1915-03-21 16:48', '1915-06-22 12:32', '1915-09-24 03:15', '1915-12-22 21:59' ); // CALL FUNC
funcAddArrayElem( result, '1916', '1916-03-20 22:37', '1916-06-21 18:20', '1916-09-23 09:04', '1916-12-22 03:48' ); // CALL FUNC
funcAddArrayElem( result, '1917', '1917-03-21 04:26', '1917-06-22 00:08', '1917-09-23 14:53', '1917-12-22 09:38' ); // CALL FUNC
funcAddArrayElem( result, '1918', '1918-03-21 10:16', '1918-06-22 05:57', '1918-09-23 20:42', '1918-12-22 15:28' ); // CALL FUNC
funcAddArrayElem( result, '1919', '1919-03-21 16:05', '1919-06-22 11:45', '1919-09-24 02:30', '1919-12-22 21:18' ); // CALL FUNC
funcAddArrayElem( result, '1920', '1920-03-20 21:54', '1920-06-21 17:33', '1920-09-23 08:19', '1920-12-22 03:07' ); // CALL FUNC
funcAddArrayElem( result, '1921', '1921-03-21 03:43', '1921-06-21 23:21', '1921-09-23 14:08', '1921-12-22 08:57' ); // CALL FUNC
funcAddArrayElem( result, '1922', '1922-03-21 09:32', '1922-06-22 05:09', '1922-09-23 19:57', '1922-12-22 14:47' ); // CALL FUNC
funcAddArrayElem( result, '1923', '1923-03-21 15:22', '1923-06-22 10:57', '1923-09-24 01:45', '1923-12-22 20:37' ); // CALL FUNC
funcAddArrayElem( result, '1924', '1924-03-20 21:11', '1924-06-21 16:45', '1924-09-23 07:34', '1924-12-22 02:26' ); // CALL FUNC
funcAddArrayElem( result, '1925', '1925-03-21 03:00', '1925-06-21 22:34', '1925-09-23 13:23', '1925-12-22 08:16' ); // CALL FUNC
funcAddArrayElem( result, '1926', '1926-03-21 08:49', '1926-06-22 04:22', '1926-09-23 19:12', '1926-12-22 14:06' ); // CALL FUNC
funcAddArrayElem( result, '1927', '1927-03-21 14:38', '1927-06-22 10:10', '1927-09-24 01:00', '1927-12-22 19:56' ); // CALL FUNC
funcAddArrayElem( result, '1928', '1928-03-20 20:28', '1928-06-21 15:58', '1928-09-23 06:49', '1928-12-22 01:45' ); // CALL FUNC
funcAddArrayElem( result, '1929', '1929-03-21 02:17', '1929-06-21 21:46', '1929-09-23 12:38', '1929-12-22 07:35' ); // CALL FUNC
funcAddArrayElem( result, '1930', '1930-03-21 08:06', '1930-06-22 03:34', '1930-09-23 18:26', '1930-12-22 13:25' ); // CALL FUNC
funcAddArrayElem( result, '1931', '1931-03-21 13:55', '1931-06-22 09:22', '1931-09-24 00:15', '1931-12-22 19:15' ); // CALL FUNC
funcAddArrayElem( result, '1932', '1932-03-20 19:44', '1932-06-21 15:11', '1932-09-23 06:04', '1932-12-22 01:04' ); // CALL FUNC
funcAddArrayElem( result, '1933', '1933-03-21 01:34', '1933-06-21 20:59', '1933-09-23 11:53', '1933-12-22 06:54' ); // CALL FUNC
funcAddArrayElem( result, '1934', '1934-03-21 07:23', '1934-06-22 02:47', '1934-09-23 17:41', '1934-12-22 12:44' ); // CALL FUNC
funcAddArrayElem( result, '1935', '1935-03-21 13:12', '1935-06-22 08:35', '1935-09-23 23:30', '1935-12-22 18:34' ); // CALL FUNC
funcAddArrayElem( result, '1936', '1936-03-20 19:01', '1936-06-21 14:23', '1936-09-23 05:19', '1936-12-22 00:23' ); // CALL FUNC
funcAddArrayElem( result, '1937', '1937-03-21 00:50', '1937-06-21 20:11', '1937-09-23 11:08', '1937-12-22 06:13' ); // CALL FUNC
funcAddArrayElem( result, '1938', '1938-03-21 06:40', '1938-06-22 01:59', '1938-09-23 16:56', '1938-12-22 12:03' ); // CALL FUNC
funcAddArrayElem( result, '1939', '1939-03-21 12:29', '1939-06-22 07:48', '1939-09-23 22:45', '1939-12-22 17:53' ); // CALL FUNC
funcAddArrayElem( result, '1940', '1940-03-20 18:18', '1940-06-21 13:36', '1940-09-23 04:34', '1940-12-21 23:42' ); // CALL FUNC
funcAddArrayElem( result, '1941', '1941-03-21 00:07', '1941-06-21 19:24', '1941-09-23 10:22', '1941-12-22 05:32' ); // CALL FUNC
funcAddArrayElem( result, '1942', '1942-03-21 05:56', '1942-06-22 01:12', '1942-09-23 16:11', '1942-12-22 11:22' ); // CALL FUNC
funcAddArrayElem( result, '1943', '1943-03-21 11:46', '1943-06-22 07:00', '1943-09-23 22:00', '1943-12-22 17:12' ); // CALL FUNC
funcAddArrayElem( result, '1944', '1944-03-20 17:35', '1944-06-21 12:48', '1944-09-23 03:49', '1944-12-21 23:01' ); // CALL FUNC
funcAddArrayElem( result, '1945', '1945-03-20 23:24', '1945-06-21 18:36', '1945-09-23 09:37', '1945-12-22 04:51' ); // CALL FUNC
funcAddArrayElem( result, '1946', '1946-03-21 05:13', '1946-06-22 00:25', '1946-09-23 15:26', '1946-12-22 10:41' ); // CALL FUNC
funcAddArrayElem( result, '1947', '1947-03-21 11:02', '1947-06-22 06:13', '1947-09-23 21:15', '1947-12-22 16:31' ); // CALL FUNC
funcAddArrayElem( result, '1948', '1948-03-20 16:52', '1948-06-21 12:01', '1948-09-23 03:03', '1948-12-21 22:20' ); // CALL FUNC
funcAddArrayElem( result, '1949', '1949-03-20 22:41', '1949-06-21 17:49', '1949-09-23 08:52', '1949-12-22 04:10' ); // CALL FUNC
funcAddArrayElem( result, '1950', '1950-03-21 04:30', '1950-06-21 23:37', '1950-09-23 14:41', '1950-12-22 10:00' ); // CALL FUNC
funcAddArrayElem( result, '1951', '1951-03-21 10:19', '1951-06-22 05:25', '1951-09-23 20:30', '1951-12-22 15:50' ); // CALL FUNC
funcAddArrayElem( result, '1952', '1952-03-20 16:08', '1952-06-21 11:13', '1952-09-23 02:18', '1952-12-21 21:39' ); // CALL FUNC
funcAddArrayElem( result, '1953', '1953-03-20 21:58', '1953-06-21 17:01', '1953-09-23 08:07', '1953-12-22 03:29' ); // CALL FUNC
funcAddArrayElem( result, '1954', '1954-03-21 03:47', '1954-06-21 22:50', '1954-09-23 13:56', '1954-12-22 09:19' ); // CALL FUNC
funcAddArrayElem( result, '1955', '1955-03-21 09:36', '1955-06-22 04:38', '1955-09-23 19:44', '1955-12-22 15:09' ); // CALL FUNC
funcAddArrayElem( result, '1956', '1956-03-20 15:25', '1956-06-21 10:26', '1956-09-23 01:33', '1956-12-21 20:58' ); // CALL FUNC
funcAddArrayElem( result, '1957', '1957-03-20 21:14', '1957-06-21 16:14', '1957-09-23 07:22', '1957-12-22 02:48' ); // CALL FUNC
funcAddArrayElem( result, '1958', '1958-03-21 03:04', '1958-06-21 22:02', '1958-09-23 13:11', '1958-12-22 08:38' ); // CALL FUNC
funcAddArrayElem( result, '1959', '1959-03-21 08:53', '1959-06-22 03:50', '1959-09-23 18:59', '1959-12-22 14:27' ); // CALL FUNC
funcAddArrayElem( result, '1960', '1960-03-20 14:42', '1960-06-21 09:38', '1960-09-23 00:48', '1960-12-21 20:17' ); // CALL FUNC
funcAddArrayElem( result, '1961', '1961-03-20 20:31', '1961-06-21 15:27', '1961-09-23 06:37', '1961-12-22 02:07' ); // CALL FUNC
funcAddArrayElem( result, '1962', '1962-03-21 02:20', '1962-06-21 21:15', '1962-09-23 12:25', '1962-12-22 07:57' ); // CALL FUNC
funcAddArrayElem( result, '1963', '1963-03-21 08:10', '1963-06-22 03:03', '1963-09-23 18:14', '1963-12-22 13:46' ); // CALL FUNC
funcAddArrayElem( result, '1964', '1964-03-20 13:59', '1964-06-21 08:51', '1964-09-23 00:03', '1964-12-21 19:36' ); // CALL FUNC
funcAddArrayElem( result, '1965', '1965-03-20 19:48', '1965-06-21 14:39', '1965-09-23 05:52', '1965-12-22 01:26' ); // CALL FUNC
funcAddArrayElem( result, '1966', '1966-03-21 01:37', '1966-06-21 20:27', '1966-09-23 11:40', '1966-12-22 07:16' ); // CALL FUNC
funcAddArrayElem( result, '1967', '1967-03-21 07:26', '1967-06-22 02:15', '1967-09-23 17:29', '1967-12-22 13:05' ); // CALL FUNC
funcAddArrayElem( result, '1968', '1968-03-20 13:16', '1968-06-21 08:03', '1968-09-22 23:18', '1968-12-21 18:55' ); // CALL FUNC
funcAddArrayElem( result, '1969', '1969-03-20 19:05', '1969-06-21 13:52', '1969-09-23 05:06', '1969-12-22 00:45' ); // CALL FUNC
funcAddArrayElem( result, '1970', '1970-03-21 00:54', '1970-06-21 19:40', '1970-09-23 10:55', '1970-12-22 06:35' ); // CALL FUNC
funcAddArrayElem( result, '1971', '1971-03-21 06:43', '1971-06-22 01:28', '1971-09-23 16:44', '1971-12-22 12:24' ); // CALL FUNC
funcAddArrayElem( result, '1972', '1972-03-20 12:32', '1972-06-21 07:16', '1972-09-22 22:33', '1972-12-21 18:14' ); // CALL FUNC
funcAddArrayElem( result, '1973', '1973-03-20 18:22', '1973-06-21 13:04', '1973-09-23 04:21', '1973-12-22 00:04' ); // CALL FUNC
funcAddArrayElem( result, '1974', '1974-03-21 00:11', '1974-06-21 18:52', '1974-09-23 10:10', '1974-12-22 05:54' ); // CALL FUNC
funcAddArrayElem( result, '1975', '1975-03-21 06:00', '1975-06-22 00:40', '1975-09-23 15:59', '1975-12-22 11:43' ); // CALL FUNC
funcAddArrayElem( result, '1976', '1976-03-20 11:49', '1976-06-21 06:29', '1976-09-22 21:47', '1976-12-21 17:33' ); // CALL FUNC
funcAddArrayElem( result, '1977', '1977-03-20 17:38', '1977-06-21 12:17', '1977-09-23 03:36', '1977-12-21 23:23' ); // CALL FUNC
funcAddArrayElem( result, '1978', '1978-03-20 23:28', '1978-06-21 18:05', '1978-09-23 09:25', '1978-12-22 05:13' ); // CALL FUNC
funcAddArrayElem( result, '1979', '1979-03-21 05:17', '1979-06-21 23:53', '1979-09-23 15:14', '1979-12-22 11:02' ); // CALL FUNC
funcAddArrayElem( result, '1980', '1980-03-20 11:06', '1980-06-21 05:41', '1980-09-22 21:02', '1980-12-21 16:52' ); // CALL FUNC
funcAddArrayElem( result, '1981', '1981-03-20 16:55', '1981-06-21 11:29', '1981-09-23 02:51', '1981-12-21 22:42' ); // CALL FUNC
funcAddArrayElem( result, '1982', '1982-03-20 22:44', '1982-06-21 17:17', '1982-09-23 08:40', '1982-12-22 04:31' ); // CALL FUNC
funcAddArrayElem( result, '1983', '1983-03-21 04:34', '1983-06-21 23:05', '1983-09-23 14:28', '1983-12-22 10:21' ); // CALL FUNC
funcAddArrayElem( result, '1984', '1984-03-20 10:23', '1984-06-21 04:54', '1984-09-22 20:17', '1984-12-21 16:11' ); // CALL FUNC
funcAddArrayElem( result, '1985', '1985-03-20 16:12', '1985-06-21 10:42', '1985-09-23 02:06', '1985-12-21 22:01' ); // CALL FUNC
funcAddArrayElem( result, '1986', '1986-03-20 22:01', '1986-06-21 16:30', '1986-09-23 07:54', '1986-12-22 03:50' ); // CALL FUNC
funcAddArrayElem( result, '1987', '1987-03-21 03:50', '1987-06-21 22:18', '1987-09-23 13:43', '1987-12-22 09:40' ); // CALL FUNC
funcAddArrayElem( result, '1988', '1988-03-20 09:40', '1988-06-21 04:06', '1988-09-22 19:32', '1988-12-21 15:30' ); // CALL FUNC
funcAddArrayElem( result, '1989', '1989-03-20 15:29', '1989-06-21 09:54', '1989-09-23 01:21', '1989-12-21 21:20' ); // CALL FUNC
funcAddArrayElem( result, '1990', '1990-03-20 21:18', '1990-06-21 15:42', '1990-09-23 07:09', '1990-12-22 03:09' ); // CALL FUNC
funcAddArrayElem( result, '1991', '1991-03-21 03:07', '1991-06-21 21:31', '1991-09-23 12:58', '1991-12-22 08:59' ); // CALL FUNC
funcAddArrayElem( result, '1992', '1992-03-20 08:56', '1992-06-21 03:19', '1992-09-22 18:47', '1992-12-21 14:49' ); // CALL FUNC
funcAddArrayElem( result, '1993', '1993-03-20 14:46', '1993-06-21 09:07', '1993-09-23 00:35', '1993-12-21 20:39' ); // CALL FUNC
funcAddArrayElem( result, '1994', '1994-03-20 20:35', '1994-06-21 14:55', '1994-09-23 06:24', '1994-12-22 02:28' ); // CALL FUNC
funcAddArrayElem( result, '1995', '1995-03-21 02:24', '1995-06-21 20:43', '1995-09-23 12:13', '1995-12-22 08:18' ); // CALL FUNC
funcAddArrayElem( result, '1996', '1996-03-20 08:13', '1996-06-21 02:31', '1996-09-22 18:01', '1996-12-21 14:08' ); // CALL FUNC
funcAddArrayElem( result, '1997', '1997-03-20 14:02', '1997-06-21 08:19', '1997-09-22 23:50', '1997-12-21 19:57' ); // CALL FUNC
funcAddArrayElem( result, '1998', '1998-03-20 19:52', '1998-06-21 14:07', '1998-09-23 05:39', '1998-12-22 01:47' ); // CALL FUNC
funcAddArrayElem( result, '1999', '1999-03-21 01:41', '1999-06-21 19:56', '1999-09-23 11:28', '1999-12-22 07:37' ); // CALL FUNC
funcAddArrayElem( result, '2000', '2000-03-20 07:30', '2000-06-21 01:44', '2000-09-22 17:16', '2000-12-21 13:27' ); // CALL FUNC
funcAddArrayElem( result, '2001', '2001-03-20 13:19', '2001-06-21 07:32', '2001-09-22 23:05', '2001-12-21 19:16' ); // CALL FUNC
funcAddArrayElem( result, '2002', '2002-03-20 19:08', '2002-06-21 13:20', '2002-09-23 04:54', '2002-12-22 01:06' ); // CALL FUNC
funcAddArrayElem( result, '2003', '2003-03-21 00:58', '2003-06-21 19:08', '2003-09-23 10:42', '2003-12-22 06:56' ); // CALL FUNC
funcAddArrayElem( result, '2004', '2004-03-20 06:47', '2004-06-21 00:56', '2004-09-22 16:31', '2004-12-21 12:46' ); // CALL FUNC
funcAddArrayElem( result, '2005', '2005-03-20 12:36', '2005-06-21 06:44', '2005-09-22 22:20', '2005-12-21 18:35' ); // CALL FUNC
funcAddArrayElem( result, '2006', '2006-03-20 18:25', '2006-06-21 12:32', '2006-09-23 04:08', '2006-12-22 00:25' ); // CALL FUNC
funcAddArrayElem( result, '2007', '2007-03-21 00:14', '2007-06-21 18:21', '2007-09-23 09:57', '2007-12-22 06:15' ); // CALL FUNC
funcAddArrayElem( result, '2008', '2008-03-20 06:04', '2008-06-21 00:09', '2008-09-22 15:46', '2008-12-21 12:04' ); // CALL FUNC
funcAddArrayElem( result, '2009', '2009-03-20 11:53', '2009-06-21 05:57', '2009-09-22 21:34', '2009-12-21 17:54' ); // CALL FUNC
funcAddArrayElem( result, '2010', '2010-03-20 17:42', '2010-06-21 11:45', '2010-09-23 03:23', '2010-12-21 23:44' ); // CALL FUNC
funcAddArrayElem( result, '2011', '2011-03-20 23:31', '2011-06-21 17:33', '2011-09-23 09:12', '2011-12-22 05:34' ); // CALL FUNC
funcAddArrayElem( result, '2012', '2012-03-20 05:20', '2012-06-20 23:21', '2012-09-22 15:01', '2012-12-21 11:23' ); // CALL FUNC
funcAddArrayElem( result, '2013', '2013-03-20 11:10', '2013-06-21 05:09', '2013-09-22 20:49', '2013-12-21 17:13' ); // CALL FUNC
funcAddArrayElem( result, '2014', '2014-03-20 16:59', '2014-06-21 10:57', '2014-09-23 02:38', '2014-12-21 23:03' ); // CALL FUNC
funcAddArrayElem( result, '2015', '2015-03-20 22:48', '2015-06-21 16:46', '2015-09-23 08:27', '2015-12-22 04:53' ); // CALL FUNC
funcAddArrayElem( result, '2016', '2016-03-20 04:37', '2016-06-20 22:34', '2016-09-22 14:15', '2016-12-21 10:42' ); // CALL FUNC
funcAddArrayElem( result, '2017', '2017-03-20 10:26', '2017-06-21 04:22', '2017-09-22 20:04', '2017-12-21 16:32' ); // CALL FUNC
funcAddArrayElem( result, '2018', '2018-03-20 16:16', '2018-06-21 10:10', '2018-09-23 01:53', '2018-12-21 22:22' ); // CALL FUNC
funcAddArrayElem( result, '2019', '2019-03-20 22:05', '2019-06-21 15:58', '2019-09-23 07:41', '2019-12-22 04:11' ); // CALL FUNC
funcAddArrayElem( result, '2020', '2020-03-20 03:54', '2020-06-20 21:46', '2020-09-22 13:30', '2020-12-21 10:01' ); // CALL FUNC
funcAddArrayElem( result, '2021', '2021-03-20 09:43', '2021-06-21 03:34', '2021-09-22 19:19', '2021-12-21 15:51' ); // CALL FUNC
funcAddArrayElem( result, '2022', '2022-03-20 15:32', '2022-06-21 09:23', '2022-09-23 01:07', '2022-12-21 21:41' ); // CALL FUNC
funcAddArrayElem( result, '2023', '2023-03-20 21:22', '2023-06-21 15:11', '2023-09-23 06:56', '2023-12-22 03:30' ); // CALL FUNC
funcAddArrayElem( result, '2024', '2024-03-20 03:11', '2024-06-20 20:59', '2024-09-22 12:45', '2024-12-21 09:20' ); // CALL FUNC
funcAddArrayElem( result, '2025', '2025-03-20 09:00', '2025-06-21 02:47', '2025-09-22 18:33', '2025-12-21 15:10' ); // CALL FUNC
funcAddArrayElem( result, '2026', '2026-03-20 14:49', '2026-06-21 08:35', '2026-09-23 00:22', '2026-12-21 20:59' ); // CALL FUNC
funcAddArrayElem( result, '2027', '2027-03-20 20:38', '2027-06-21 14:23', '2027-09-23 06:11', '2027-12-22 02:49' ); // CALL FUNC
funcAddArrayElem( result, '2028', '2028-03-20 02:28', '2028-06-20 20:11', '2028-09-22 11:59', '2028-12-21 08:39' ); // CALL FUNC
funcAddArrayElem( result, '2029', '2029-03-20 08:17', '2029-06-21 01:59', '2029-09-22 17:48', '2029-12-21 14:29' ); // CALL FUNC
funcAddArrayElem( result, '2030', '2030-03-20 14:06', '2030-06-21 07:48', '2030-09-22 23:37', '2030-12-21 20:18' ); // CALL FUNC
funcAddArrayElem( result, '2031', '2031-03-20 19:55', '2031-06-21 13:36', '2031-09-23 05:26', '2031-12-22 02:08' ); // CALL FUNC
funcAddArrayElem( result, '2032', '2032-03-20 01:44', '2032-06-20 19:24', '2032-09-22 11:14', '2032-12-21 07:58' ); // CALL FUNC
funcAddArrayElem( result, '2033', '2033-03-20 07:34', '2033-06-21 01:12', '2033-09-22 17:03', '2033-12-21 13:48' ); // CALL FUNC
funcAddArrayElem( result, '2034', '2034-03-20 13:23', '2034-06-21 07:00', '2034-09-22 22:52', '2034-12-21 19:37' ); // CALL FUNC
funcAddArrayElem( result, '2035', '2035-03-20 19:12', '2035-06-21 12:48', '2035-09-23 04:40', '2035-12-22 01:27' ); // CALL FUNC
funcAddArrayElem( result, '2036', '2036-03-20 01:01', '2036-06-20 18:36', '2036-09-22 10:29', '2036-12-21 07:17' ); // CALL FUNC
funcAddArrayElem( result, '2037', '2037-03-20 06:50', '2037-06-21 00:24', '2037-09-22 16:18', '2037-12-21 13:06' ); // CALL FUNC
funcAddArrayElem( result, '2038', '2038-03-20 12:40', '2038-06-21 06:13', '2038-09-22 22:06', '2038-12-21 18:56' ); // CALL FUNC
funcAddArrayElem( result, '2039', '2039-03-20 18:29', '2039-06-21 12:01', '2039-09-23 03:55', '2039-12-22 00:46' ); // CALL FUNC
funcAddArrayElem( result, '2040', '2040-03-20 00:18', '2040-06-20 17:49', '2040-09-22 09:44', '2040-12-21 06:36' ); // CALL FUNC
funcAddArrayElem( result, '2041', '2041-03-20 06:07', '2041-06-20 23:37', '2041-09-22 15:32', '2041-12-21 12:25' ); // CALL FUNC
funcAddArrayElem( result, '2042', '2042-03-20 11:56', '2042-06-21 05:25', '2042-09-22 21:21', '2042-12-21 18:15' ); // CALL FUNC
funcAddArrayElem( result, '2043', '2043-03-20 17:46', '2043-06-21 11:13', '2043-09-23 03:10', '2043-12-22 00:05' ); // CALL FUNC
funcAddArrayElem( result, '2044', '2044-03-19 23:35', '2044-06-20 17:01', '2044-09-22 08:58', '2044-12-21 05:54' ); // CALL FUNC
funcAddArrayElem( result, '2045', '2045-03-20 05:24', '2045-06-20 22:49', '2045-09-22 14:47', '2045-12-21 11:44' ); // CALL FUNC
funcAddArrayElem( result, '2046', '2046-03-20 11:13', '2046-06-21 04:37', '2046-09-22 20:36', '2046-12-21 17:34' ); // CALL FUNC
funcAddArrayElem( result, '2047', '2047-03-20 17:02', '2047-06-21 10:26', '2047-09-23 02:24', '2047-12-21 23:24' ); // CALL FUNC
funcAddArrayElem( result, '2048', '2048-03-19 22:52', '2048-06-20 16:14', '2048-09-22 08:13', '2048-12-21 05:13' ); // CALL FUNC
funcAddArrayElem( result, '2049', '2049-03-20 04:41', '2049-06-20 22:02', '2049-09-22 14:02', '2049-12-21 11:03' ); // CALL FUNC
funcAddArrayElem( result, '2050', '2050-03-20 10:30', '2050-06-21 03:50', '2050-09-22 19:50', '2050-12-21 16:53' ); // CALL FUNC
funcAddArrayElem( result, '2051', '2051-03-20 16:19', '2051-06-21 09:38', '2051-09-23 01:39', '2051-12-21 22:42' ); // CALL FUNC
funcAddArrayElem( result, '2052', '2052-03-19 22:08', '2052-06-20 15:26', '2052-09-22 07:28', '2052-12-21 04:32' ); // CALL FUNC
funcAddArrayElem( result, '2053', '2053-03-20 03:58', '2053-06-20 21:14', '2053-09-22 13:16', '2053-12-21 10:22' ); // CALL FUNC
funcAddArrayElem( result, '2054', '2054-03-20 09:47', '2054-06-21 03:02', '2054-09-22 19:05', '2054-12-21 16:12' ); // CALL FUNC
funcAddArrayElem( result, '2055', '2055-03-20 15:36', '2055-06-21 08:51', '2055-09-23 00:54', '2055-12-21 22:01' ); // CALL FUNC
funcAddArrayElem( result, '2056', '2056-03-19 21:25', '2056-06-20 14:39', '2056-09-22 06:42', '2056-12-21 03:51' ); // CALL FUNC
funcAddArrayElem( result, '2057', '2057-03-20 03:14', '2057-06-20 20:27', '2057-09-22 12:31', '2057-12-21 09:41' ); // CALL FUNC
funcAddArrayElem( result, '2058', '2058-03-20 09:04', '2058-06-21 02:15', '2058-09-22 18:20', '2058-12-21 15:30' ); // CALL FUNC
funcAddArrayElem( result, '2059', '2059-03-20 14:53', '2059-06-21 08:03', '2059-09-23 00:08', '2059-12-21 21:20' ); // CALL FUNC
funcAddArrayElem( result, '2060', '2060-03-19 20:42', '2060-06-20 13:51', '2060-09-22 05:57', '2060-12-21 03:10' ); // CALL FUNC
funcAddArrayElem( result, '2061', '2061-03-20 02:31', '2061-06-20 19:39', '2061-09-22 11:46', '2061-12-21 09:00' ); // CALL FUNC
funcAddArrayElem( result, '2062', '2062-03-20 08:20', '2062-06-21 01:27', '2062-09-22 17:34', '2062-12-21 14:49' ); // CALL FUNC
funcAddArrayElem( result, '2063', '2063-03-20 14:10', '2063-06-21 07:16', '2063-09-22 23:23', '2063-12-21 20:39' ); // CALL FUNC
funcAddArrayElem( result, '2064', '2064-03-19 19:59', '2064-06-20 13:04', '2064-09-22 05:12', '2064-12-21 02:29' ); // CALL FUNC
funcAddArrayElem( result, '2065', '2065-03-20 01:48', '2065-06-20 18:52', '2065-09-22 11:00', '2065-12-21 08:18' ); // CALL FUNC
funcAddArrayElem( result, '2066', '2066-03-20 07:37', '2066-06-21 00:40', '2066-09-22 16:49', '2066-12-21 14:08' ); // CALL FUNC
funcAddArrayElem( result, '2067', '2067-03-20 13:26', '2067-06-21 06:28', '2067-09-22 22:38', '2067-12-21 19:58' ); // CALL FUNC
funcAddArrayElem( result, '2068', '2068-03-19 19:16', '2068-06-20 12:16', '2068-09-22 04:26', '2068-12-21 01:47' ); // CALL FUNC
funcAddArrayElem( result, '2069', '2069-03-20 01:05', '2069-06-20 18:04', '2069-09-22 10:15', '2069-12-21 07:37' ); // CALL FUNC
funcAddArrayElem( result, '2070', '2070-03-20 06:54', '2070-06-20 23:52', '2070-09-22 16:04', '2070-12-21 13:27' ); // CALL FUNC
funcAddArrayElem( result, '2071', '2071-03-20 12:43', '2071-06-21 05:41', '2071-09-22 21:52', '2071-12-21 19:17' ); // CALL FUNC
funcAddArrayElem( result, '2072', '2072-03-19 18:32', '2072-06-20 11:29', '2072-09-22 03:41', '2072-12-21 01:06' ); // CALL FUNC
funcAddArrayElem( result, '2073', '2073-03-20 00:22', '2073-06-20 17:17', '2073-09-22 09:30', '2073-12-21 06:56' ); // CALL FUNC
funcAddArrayElem( result, '2074', '2074-03-20 06:11', '2074-06-20 23:05', '2074-09-22 15:18', '2074-12-21 12:46' ); // CALL FUNC
funcAddArrayElem( result, '2075', '2075-03-20 12:00', '2075-06-21 04:53', '2075-09-22 21:07', '2075-12-21 18:35' ); // CALL FUNC
funcAddArrayElem( result, '2076', '2076-03-19 17:49', '2076-06-20 10:41', '2076-09-22 02:56', '2076-12-21 00:25' ); // CALL FUNC
funcAddArrayElem( result, '2077', '2077-03-19 23:38', '2077-06-20 16:29', '2077-09-22 08:44', '2077-12-21 06:15' ); // CALL FUNC
funcAddArrayElem( result, '2078', '2078-03-20 05:28', '2078-06-20 22:17', '2078-09-22 14:33', '2078-12-21 12:05' ); // CALL FUNC
funcAddArrayElem( result, '2079', '2079-03-20 11:17', '2079-06-21 04:05', '2079-09-22 20:22', '2079-12-21 17:54' ); // CALL FUNC
funcAddArrayElem( result, '2080', '2080-03-19 17:06', '2080-06-20 09:54', '2080-09-22 02:10', '2080-12-20 23:44' ); // CALL FUNC
funcAddArrayElem( result, '2081', '2081-03-19 22:55', '2081-06-20 15:42', '2081-09-22 07:59', '2081-12-21 05:34' ); // CALL FUNC
funcAddArrayElem( result, '2082', '2082-03-20 04:44', '2082-06-20 21:30', '2082-09-22 13:48', '2082-12-21 11:23' ); // CALL FUNC
funcAddArrayElem( result, '2083', '2083-03-20 10:34', '2083-06-21 03:18', '2083-09-22 19:36', '2083-12-21 17:13' ); // CALL FUNC
funcAddArrayElem( result, '2084', '2084-03-19 16:23', '2084-06-20 09:06', '2084-09-22 01:25', '2084-12-20 23:03' ); // CALL FUNC
funcAddArrayElem( result, '2085', '2085-03-19 22:12', '2085-06-20 14:54', '2085-09-22 07:14', '2085-12-21 04:52' ); // CALL FUNC
funcAddArrayElem( result, '2086', '2086-03-20 04:01', '2086-06-20 20:42', '2086-09-22 13:02', '2086-12-21 10:42' ); // CALL FUNC
funcAddArrayElem( result, '2087', '2087-03-20 09:50', '2087-06-21 02:30', '2087-09-22 18:51', '2087-12-21 16:32' ); // CALL FUNC
funcAddArrayElem( result, '2088', '2088-03-19 15:40', '2088-06-20 08:19', '2088-09-22 00:39', '2088-12-20 22:22' ); // CALL FUNC
funcAddArrayElem( result, '2089', '2089-03-19 21:29', '2089-06-20 14:07', '2089-09-22 06:28', '2089-12-21 04:11' ); // CALL FUNC
funcAddArrayElem( result, '2090', '2090-03-20 03:18', '2090-06-20 19:55', '2090-09-22 12:17', '2090-12-21 10:01' ); // CALL FUNC
funcAddArrayElem( result, '2091', '2091-03-20 09:07', '2091-06-21 01:43', '2091-09-22 18:05', '2091-12-21 15:51' ); // CALL FUNC
funcAddArrayElem( result, '2092', '2092-03-19 14:56', '2092-06-20 07:31', '2092-09-21 23:54', '2092-12-20 21:40' ); // CALL FUNC
funcAddArrayElem( result, '2093', '2093-03-19 20:46', '2093-06-20 13:19', '2093-09-22 05:43', '2093-12-21 03:30' ); // CALL FUNC
funcAddArrayElem( result, '2094', '2094-03-20 02:35', '2094-06-20 19:07', '2094-09-22 11:31', '2094-12-21 09:20' ); // CALL FUNC
funcAddArrayElem( result, '2095', '2095-03-20 08:24', '2095-06-21 00:55', '2095-09-22 17:20', '2095-12-21 15:09' ); // CALL FUNC
funcAddArrayElem( result, '2096', '2096-03-19 14:13', '2096-06-20 06:43', '2096-09-21 23:09', '2096-12-20 20:59' ); // CALL FUNC
funcAddArrayElem( result, '2097', '2097-03-19 20:02', '2097-06-20 12:32', '2097-09-22 04:57', '2097-12-21 02:49' ); // CALL FUNC
funcAddArrayElem( result, '2098', '2098-03-20 01:52', '2098-06-20 18:20', '2098-09-22 10:46', '2098-12-21 08:39' ); // CALL FUNC
funcAddArrayElem( result, '2099', '2099-03-20 07:41', '2099-06-21 00:08', '2099-09-22 16:35', '2099-12-21 14:28' ); // CALL FUNC
funcAddArrayElem( result, '2100', '2100-03-20 13:30', '2100-06-21 05:56', '2100-09-22 22:23', '2100-12-21 20:18' ); // CALL FUNC
//**************************************************************************
//**************************************************************************
//**************************************************************************
//**************************************************************************
//**************************************************************************
end;
//--------------------------------------------------------------------------80
function funcFindDateTimeByYear(AYear: WideString;
ADateTime: TidElement): Integer;
var
i: Integer;
AElem: TidElement;
begin
Result := -1; // value if no match found
for i := 0 to ADateTime.Elements.Count - 1 do
begin
AElem := ADateTime.Elements.Items[i];
if (AElem.Prop['Year'] = AYear) then
begin
Result := i; // value if match found
Exit; // exit function
end;
end;
ADateTime.Free;
end;
//--------------------------------------------------------------------------80
function funcFormatDateTimeString(ADateTimeString: WideString): WideString;
// convert specified input format to TDateTime format
//
// input format: yyyy-mm-dd hh:nn:ss
// output format: dd/mm/yyyy hh:nn:ss
//
// NOTE For input format, 'ss' and 'nn' may both be omitted,
// ie the following are acceptable:
// yyyy-mm-dd hh:nn:ss
// yyyy-mm-dd hh:nn
// yyyy-mm-dd hh
var
i: Integer;
yyyy, mm, dd, hhnnss: WideString;
ATokens: TTntStringList;
ASubTokens: TTntStringList;
begin
result := 'bad datetime string';
yyyy := ''; mm := ''; dd := ''; hhnnss := '';
ATokens := TTntStringList.Create;
ASubTokens := TTntStringList.Create;
try
Tokenize(ADateTimeString, '-', ATokens);
for i := 0 to ATokens.Count - 1 do
begin
if (Pos (' ', ATokens.Strings[i]) = 0) then
ASubTokens.Add(ATokens.Strings[i]);
else
Tokenize(ATokens.Strings[i], ' ', ASubTokens);
end;
if ASubTokens.Count >= 4 then
begin
yyyy := ASubTokens.Strings[0];
mm := ASubTokens.Strings[1];
dd := ASubTokens.Strings[2];
hhnnss := ASubTokens.Strings[3];
end;
result := dd + '/' + mm + '/' + yyyy + ' ' + hhnnss;
finally
ATokens.Free;
ASubTokens.Free;
end;
end;
//--------------------------------------------------------------------------80
function funcFormatISODateTimeString(ADateTimeString: WideString): WideString;
// convert specified input format to TDateTime format
//
// input format: yyyy-mm-dd hh:nn:ss
// output format: yyyy-mm-ddThh:nn:ss.zzzZ
//
// NOTE For input format, 'ss' and 'nn' may both be omitted,
// ie the following are acceptable:
// yyyy-mm-dd hh:nn:ss
// yyyy-mm-dd hh:nn
// yyyy-mm-dd hh
var
i: Integer;
yyyy, mm, dd, hhnnss: WideString;
ATokens: TTntStringList;
ASubTokens: TTntStringList;
begin
result := 'bad datetime string';
yyyy := ''; mm := ''; dd := ''; hhnnss := '';
ATokens := TTntStringList.Create;
ASubTokens := TTntStringList.Create;
try
Tokenize(ADateTimeString, '-', ATokens);
for i := 0 to ATokens.Count - 1 do
begin
if (Pos (' ', ATokens.Strings[i]) = 0) then
ASubTokens.Add(ATokens.Strings[i]);
else
Tokenize(ATokens.Strings[i], ' ', ASubTokens);
end;
if ASubTokens.Count >= 4 then
begin
yyyy := ASubTokens.Strings[0];
mm := ASubTokens.Strings[1];
dd := ASubTokens.Strings[2];
hhnnss := ASubTokens.Strings[3];
end;
result := yyyy + '-' + mm + '-' + dd + 'T' + hhnnss + '.000Z';
finally
ATokens.Free;
ASubTokens.Free;
end;
end;
//--------------------------------------------------------------------------80
function funcGetSeasonAstroNorth(APhotoDate: TDateTime): WideString;
{
CompareDateTime compares two TDateTime values A and B and returns:
< 0 if A is earlier than B
= 0 if A and B are the same date/time
> 0 if A is later than B
}
var
AArrayIndex: Integer;
AYear: WideString;
ATokens: TTntStringList;
ADT1, ADT2: TDateTime;
AArrayDateTime, AElem: TidElement;
ATimeZoneOffset: Double;
begin
result := '';
ATokens := TTntStringList.Create;
Tokenize(DateTimeToISODateString(APhotoDate, TimeZoneOffset, dtkDateTime), '-', ATokens);
if ATokens.Count >= 2 then
begin
AYear := ATokens.Strings[0];
AArrayDateTime := funcInitArray(); // CALL FUNC
AArrayIndex := funcFindDateTimeByYear(AYear, AArrayDateTime); // CALL FUNC
if (AArrayIndex = -1) then
result := 'YEAR MATCH NOT FOUND';
else
begin
ATimeZoneOffset := 0.0;
AElem := AArrayDateTime.Elements.Items[AArrayIndex];
ADT1 := APhotoDate;
ADT2 := ISODateStringToDateTime(funcFormatISODateTimeString(AElem.Prop['MarE']), ATimeZoneOffset); // CALL FUNC
if CompareDateTime(ADT1, ADT2) < 0 then
result := 'Winter';
if CompareDateTime(ADT1, ADT2) >= 0 then
result := 'Spring';
ADT2 := ISODateStringToDateTime(funcFormatISODateTimeString(AElem.Prop['JunS']), ATimeZoneOffset); // CALL FUNC
if CompareDateTime(ADT1, ADT2) >= 0 then
result := 'Summer';
ADT2 := ISODateStringToDateTime(funcFormatISODateTimeString(AElem.Prop['SepE']), ATimeZoneOffset); // CALL FUNC
if CompareDateTime(ADT1, ADT2) >= 0 then
result := 'Autumn';
ADT2 := ISODateStringToDateTime(funcFormatISODateTimeString(AElem.Prop['DecS']), ATimeZoneOffset); // CALL FUNC
if CompareDateTime(ADT1, ADT2) >= 0 then
result := 'Winter';
end;
end
else
result := 'INVALID PHOTO DATE';
ATokens.Free;
end;
//--------------------------------------------------------------------------80
function funcGetSeasonAstroSouth(APhotoDate: TDateTime): WideString;
{
CompareDateTime compares two TDateTime values A and B and returns:
< 0 if A is earlier than B
= 0 if A and B are the same date/time
> 0 if A is later than B
}
var
AArrayIndex: Integer;
AYear: WideString;
ATokens: TTntStringList;
ADT1, ADT2: TDateTime;
AArrayDateTime, AElem: TidElement;
ATimeZoneOffset: Double;
begin
result := '';
ATokens := TTntStringList.Create;
Tokenize(DateTimeToISODateString(APhotoDate, TimeZoneOffset, dtkDateTime), '-', ATokens);
if ATokens.Count >= 2 then
begin
AYear := ATokens.Strings[0];
AArrayDateTime := funcInitArray(); // CALL FUNC
AArrayIndex := funcFindDateTimeByYear(AYear, AArrayDateTime); // CALL FUNC
if (AArrayIndex = -1) then
result := 'YEAR MATCH NOT FOUND';
else
begin
ATimeZoneOffset := 0.0;
AElem := AArrayDateTime.Elements.Items[AArrayIndex];
ADT1 := APhotoDate;
ADT2 := ISODateStringToDateTime(funcFormatISODateTimeString(AElem.Prop['MarE']), ATimeZoneOffset); // CALL FUNC
if CompareDateTime(ADT1, ADT2) < 0 then
result := 'Summer';
if CompareDateTime(ADT1, ADT2) >= 0 then
result := 'Autumn';
ADT2 := ISODateStringToDateTime(funcFormatISODateTimeString(AElem.Prop['JunS']), ATimeZoneOffset); // CALL FUNC
if CompareDateTime(ADT1, ADT2) >= 0 then
result := 'Winter';
ADT2 := ISODateStringToDateTime(funcFormatISODateTimeString(AElem.Prop['SepE']), ATimeZoneOffset); // CALL FUNC
if CompareDateTime(ADT1, ADT2) >= 0 then
result := 'Spring';
ADT2 := ISODateStringToDateTime(funcFormatISODateTimeString(AElem.Prop['DecS']), ATimeZoneOffset); // CALL FUNC
if CompareDateTime(ADT1, ADT2) >= 0 then
result := 'Summer';
end;
end
else
result := 'INVALID PHOTO DATE';
ATokens.Free;
end;
//--------------------------------------------------------------------------80
function funcGetSeasonMeteoNorth(APhotoDate: TDateTime): WideString;
var
AMonth: Integer;
ATokens: TTntStringList;
begin
result := '';
ATokens := TTntStringList.Create;
Tokenize(DateTimeToISODateString(APhotoDate, TimeZoneOffset, dtkDateTime), '-', ATokens);
if ATokens.Count >= 3 then
begin
AMonth := StrToInt(ATokens.Strings[1]);
if (AMonth >= 3) AND (AMonth < 6) then
result := 'Spring';
if (AMonth >= 6) AND (AMonth < 9) then
result := 'Summer';
if (AMonth >= 9) AND (AMonth < 12) then
result := 'Autumn';
if (AMonth = 12) OR (AMonth = 1) OR (AMonth = 2) then
result := 'Winter';
end
else
result := 'INVALID PHOTO DATE';
ATokens.Free;
end;
//--------------------------------------------------------------------------80
function funcGetSeasonMeteoSouth(APhotoDate: TDateTime): WideString;
var
AMonth: Integer;
ATokens: TTntStringList;
begin
result := '';
ATokens := TTntStringList.Create;
Tokenize(DateTimeToISODateString(APhotoDate, TimeZoneOffset, dtkDateTime), '-', ATokens);
if ATokens.Count >= 3 then
begin
AMonth := StrToInt(ATokens.Strings[1]);
if (AMonth >= 3) AND (AMonth < 6) then
result := 'Autumn';
if (AMonth >= 6) AND (AMonth < 9) then
result := 'Winter';
if (AMonth >= 9) AND (AMonth < 12) then
result := 'Spring';
if (AMonth = 12) OR (AMonth = 1) OR (AMonth = 2) then
result := 'Summer';
end
else
result := 'INVALID PHOTO DATE';
ATokens.Free;
end;
//----------------------------------------------------------------------------80
var { main procedure }
i: Integer;
AIntAskButton: Integer;
ABlnAskChecked: Boolean;
ABlnInvalidDir: Boolean;
AWStrCollName: WideString;
AWStrCollDescription: WideString;
AWStrDateTimeDescription: WideString;
AWStrDateTimeSuffix: WideString;
AWStrReportFile: WideString;
AWStrReportName: WideString;
AWStrReportPath: WideString;
AWStrItemName: WideString;
AWStrMessage: WideString;
AWStrParentGUID: WideString;
AWStrParentName: WideString;
AWStrPortName: WideString;
AWStrPortDescription: WideString;
AWStrSeasonAstro: WideString;
AWStrSeasonMeteo: WideString;
AWStrSelectedObject: WideString;
AWStrWarning: WideString;
AWStrWarningAstro: WideString;
AWStrWarningMeteo: WideString;
AWStrListReportLine: TStringList;
AWStrListReportText: TStringList;
AStrListParents: TStringList;
ATStrListAskOptions: TTntStringList;
ATStrListImgItemAstro: TTntStringList;
ATStrListImgItemMeteo: TTntStringList;
ACatPropGroup: TCatalogPropGroup;
AImgItem: TImageItem;
AImgColl: TImageCollection;
AImgColls: TImageCollections;
AImgCollSeason: TImageCollection;
AImgCollSeasonDateTime: TImageCollection;
AImgCollSeasonAstro: TImageCollection;
AImgCollSeasonAstroWinter: TImageCollection;
AImgCollSeasonAstroSpring: TImageCollection;
AImgCollSeasonAstroSummer: TImageCollection;
AImgCollSeasonAstroAutumn: TImageCollection;
AImgCollSeasonAstronotassigned: TImageCollection;
AImgCollSeasonMeteo: TImageCollection;
AImgCollSeasonMeteoWinter: TImageCollection;
AImgCollSeasonMeteoSpring: TImageCollection;
AImgCollSeasonMeteoSummer: TImageCollection;
AImgCollSeasonMeteoAutumn: TImageCollection;
AImgCollSeasonMeteonotassigned: TImageCollection;
AImgModel: TImageModel;
AImgGallery: TImageGallery;
AxomProgress: TxomProgress;
// ACatItemElem: TidElement; // FOR ARRAY METHOD
begin
// check at least one season constant set to True
if not cASeasonAstroSort and not cASeasonMeteoSort then
begin
Say2('No Seasons Sorted',
'Please edit script to sort at least one season type.' + CrLf +
'Current settings are:' + CrLf2 +
' (0=no, 1=yes)' + CrLf +
' cASeasonAstroSort = ' + IntToStr(cASeasonAstroSort) + CrLf +
' cASeasonAstroDataSet = ' + WideString(cASeasonAstroDataSet) + CrLf +
' cASeasonMeteoSort = ' + IntToStr(cASeasonMeteoSort) + CrLf +
' cASeasonHemisphere = ' + WideString(cASeasonHemisphere) + CrLf +
' cASeasonAddLabel = ' + IntToStr(cASeasonAddLabel));
Exit; // exit script
end;
// prepare date time strings
AWStrDateTimeDescription := FormatDateTime('yyyy-mm-dd hh:mm:ss', Now); // global var assign
AWStrDateTimeSuffix := StringReplace(AWStrDateTimeDescription, '-', '', [0]); // THIS WORKS
AWStrDateTimeSuffix := StringReplace(AWStrDateTimeSuffix, ':', '', [0]); // THIS WORKS
AWStrDateTimeSuffix := StringReplace(AWStrDateTimeSuffix, ' ', '_', [0]); // THIS WORKS
// initialise report text string list
AWStrListReportText := TStringList.Create;
AWStrListReportText.Add(UTF8Encode(''));
// STEP 00 - GET SELECTED ITEM(S)
ACatPropGroup := SearchGroup;
// STEP 01 - CREATE
// SELECTED ITEM IS AN IMAGE OR A COLLECTION
// create season collection and date time collection
if ACatPropGroup.Collections.Count > 0 then
begin
// get collection parent portfolio, gallery and collections
AImgModel := TImageModel.Create(nil);
AImgGallery := TImageGallery.Create(nil);
AStrListParents := TStringList.Create;
AImgColls := TImageCollections.Create(TImageCollection, '');
PublicCatalog.EnumModelForCollection(ACatPropGroup.Collections.Items[0], AImgModel);
PublicCatalog.EnumGalleryForCollection(ACatPropGroup.Collections.Items[0], AImgGallery);
PublicCatalog.EnumCollectionParents(ACatPropGroup.Collections.Items[0].GUID, AStrListParents);
PublicCatalog.EnumCollectionsforParent(ACatPropGroup.Collections.Items[0].GUID, AImgColls);
if AStrListParents <> nil then
begin
// assign parent GUID and name
if AStrListParents.Count = 1 then // COLLECTION PARENT IS A PORTFOLIO
begin
AWStrParentGUID := AImgGallery.GUID;
AWStrParentName := AImgModel.ModelName;
end
else // COLLECTION PARENT IS A COLLECTION
begin
AImgColl := TImageCollection.Create(nil);
PublicCatalog.EnumCollectionByGUID(AStrListParents.Strings[AStrListParents.Count-2], AImgColl);
AWStrParentGUID := AImgColl.GUID;
AWStrParentName := AImgColl.CollectionName;
AImgColl.Free;
end;
// create parent collections
AWStrCollName := ACatPropGroup.Collections.Items[0].CollectionName + ' - Season';
AWStrCollDescription := 'created: ' + AWStrDateTimeDescription + CrLf +
'original collection: ' + ACatPropGroup.Collections.Items[0].CollectionName + CrLf +
'original collection parent: ' + AWStrParentName + CrLf +
'original collection gallery: ' + AImgGallery.GalleryName + CrLf +
'original collection portfolio: ' + AImgModel.ModelName;
AImgCollSeason := funcCreateCollection(AWStrParentGUID, AWStrCollName, AWStrCollDescription); // CALL FUNC
AImgCollSeasonDateTime := funcCreateCollection(AImgCollSeason.GUID, 'Season_' + AWStrDateTimeSuffix, AWStrCollDescription); // CALL FUNC
end;
AImgModel.Free;
AImgGallery.Free;
AStrListParents.Free;
AImgColls.Free;
end
// STEP 02 - CREATE
// SELECTED ITEM IS A PORTFOLIO
// create season portfolio and date time collection
else if ACatPropGroup.Albums.Count > 0 then
begin
AImgModel := TImageModel.Create(nil);
AImgGallery := TImageGallery.Create(nil);
// create parent portfolio
AWStrPortName := ACatPropGroup.Albums.Items[0].ModelName + ' - Season';
AWStrPortDescription:= 'created: ' + AWStrDateTimeDescription + CrLf +
'original portfolio: ' + ACatPropGroup.Albums.Items[0].ModelName;
procCreatePortfolioNamed(AWStrPortName, AWStrPortDescription); // CALL PROC
// create parent collection
PublicCatalog.EnumModelNamed(AWStrPortName, AImgModel);
PublicCatalog.EnumModelGalleryNamed(AWStrPortName, AImgModel, AImgGallery);
AImgCollSeasonDateTime := funcCreateCollection(AImgGallery.GUID, 'Season_' + AWStrDateTimeSuffix, AWStrPortDescription); // CALL FUNC
AImgModel.Free;
AImgGallery.Free;
end
// STEP 03 - CREATE
// SELECTED ITEM IS NOT AN IMAGE, A COLLECTION OR A PORTFOLIO
else
begin
Say('Please select an Image, Collection or Portfolio (under Portfolios tab).');
Exit; // exit script
end;
// STEP 04 - CREATE
// CREATE SEASON SUB COLLECTIONS
if cASeasonAstroSort then
begin
AWStrCollDescription := cASeasonHemisphere + ' Hemisphere' + CrLf + cASeasonAstroDataSet;
// create astronomical season collection for season date time collection
AImgCollSeasonAstro := funcCreateCollection(AImgCollSeasonDateTime.GUID, 'Astronomical', AWStrCollDescription); // CALL FUNC
// create seasons collections for astronomical season collection
AImgCollSeasonAstroWinter := funcCreateCollection(AImgCollSeasonAstro.GUID, 'Winter', AWStrCollDescription); // CALL FUNC
AImgCollSeasonAstroSpring := funcCreateCollection(AImgCollSeasonAstro.GUID, 'Spring', AWStrCollDescription); // CALL FUNC
AImgCollSeasonAstroSummer := funcCreateCollection(AImgCollSeasonAstro.GUID, 'Summer', AWStrCollDescription); // CALL FUNC
AImgCollSeasonAstroAutumn := funcCreateCollection(AImgCollSeasonAstro.GUID, 'Autumn', AWStrCollDescription); // CALL FUNC
AImgCollSeasonAstronotassigned := funcCreateCollection(AImgCollSeasonAstro.GUID, 'not assigned', 'Photo Date Issue: no year match found.'); // CALL FUNC
end;
if cASeasonMeteoSort then
begin
AWStrCollDescription := cASeasonHemisphere + ' Hemisphere';
// create meteorological season collection for season date time collection
AImgCollSeasonMeteo := funcCreateCollection(AImgCollSeasonDateTime.GUID, 'Meteorological', AWStrCollDescription); // CALL FUNC
// create seasons collections for meteorological season collection
AImgCollSeasonMeteoWinter := funcCreateCollection(AImgCollSeasonMeteo.GUID, 'Winter', AWStrCollDescription); // CALL FUNC
AImgCollSeasonMeteoSpring := funcCreateCollection(AImgCollSeasonMeteo.GUID, 'Spring', AWStrCollDescription); // CALL FUNC
AImgCollSeasonMeteoSummer := funcCreateCollection(AImgCollSeasonMeteo.GUID, 'Summer', AWStrCollDescription); // CALL FUNC
AImgCollSeasonMeteoAutumn := funcCreateCollection(AImgCollSeasonMeteo.GUID, 'Autumn', AWStrCollDescription); // CALL FUNC
AImgCollSeasonMeteonotassigned := funcCreateCollection(AImgCollSeasonMeteo.GUID, 'not assigned', 'Photo Date Issue: no month match found.'); // CALL FUNC
end;
// STEP 05 - PROCESS
// SELECTED ITEM IS AN IMAGE
if Selected.Count > 0 then
begin
// initialise progress bar
AxomProgress := TxomProgress.Create(nil);
AxomProgress.Caption := 'Processing Selected Items...';
AxomProgress.Pos := 0;
AxomProgress.Max := Selected.Count;
AxomProgress.CanCancel := True;
AxomProgress.Show;
// sort selected items
ATStrListImgItemAstro := TTntStringList.Create;
ATStrListImgItemMeteo := TTntStringList.Create;
for i := 0 to Selected.Count - 1 do
begin
// '.ImageName' is no longer working
// // some items return AImgItem.ImageName without extension:
// if ExtractFileExt(Selected.Items[i].ImageName) = '' then
// AWStrItemName := Selected.Items[i].ImageName + ExtractFileExt(Selected.Items[i].FileName);
// else
// AWStrItemName := Selected.Items[i].ImageName;
// get item name
AWStrItemName := WideExtractFileName(Selected.Items[i].FileName);
// update progress bar
AxomProgress.Pos := i + 1;
AxomProgress.ProgressText := 'item ' + IntToStr(i) + ' of ' +
IntToStr(Selected.Count) + ': ' +
AWStrItemName;
if AxomProgress.Cancel then
Break; // exit for-loop
// get item season
AWStrWarningAstro := '';
AWStrWarningMeteo := '';
// store as astronomical season if sort switch on
if cASeasonAstroSort then
begin
AWStrSeasonAstro := iif(cASeasonHemisphere = 'Northern',
funcGetSeasonAstroNorth(Selected.Items[i].PhotoDate),
funcGetSeasonAstroSouth(Selected.Items[i].PhotoDate)); // CALL FUNC
// add season label to item
if cASeasonAddLabel and (Length(AWStrSeasonAstro) = 6) then // if switch on and valid season
procLabelImgItemKeywords(Selected.Items[i], 'astronomical ' + WideLowerCase(AWStrSeasonAstro)); // CALL PROC
// store item to collection
Case funcChangeToTitleCase(AWStrSeasonAstro) of // CALL FUNC
'Winter': PublicCatalog.StoreItemToCollection(Selected.Items[i], AImgCollSeasonAstroWinter, PublicOptions.XMPSyncReadSettings, False);
'Spring': PublicCatalog.StoreItemToCollection(Selected.Items[i], AImgCollSeasonAstroSpring, PublicOptions.XMPSyncReadSettings, False);
'Summer': PublicCatalog.StoreItemToCollection(Selected.Items[i], AImgCollSeasonAstroSummer, PublicOptions.XMPSyncReadSettings, False);
'Autumn': PublicCatalog.StoreItemToCollection(Selected.Items[i], AImgCollSeasonAstroAutumn, PublicOptions.XMPSyncReadSettings, False);
else
begin
AWStrWarningAstro := 'Astro warning: some seasons not assigned' + CrLf;
PublicCatalog.StoreItemToCollection(Selected.Items[i], AImgCollSeasonAstronotassigned, PublicOptions.XMPSyncReadSettings, False);
end;
end;
AWStrListReportLine := TStringList.Create;
AWStrListReportLine.Add(UTF8Encode(IntToStr(i)));
AWStrListReportLine.Add(UTF8Encode('ASTRO'));
AWStrListReportLine.Add(UTF8Encode(funcChangeToTitleCase(AWStrSeasonAstro))); // CALL FUNC
AWStrListReportLine.Add(UTF8Encode(DateTimeToExifDate(Selected.Items[i].PhotoDate)));
AWStrListReportLine.Add(UTF8Encode(AWStrItemName));
AWStrListReportLine.Add(UTF8Encode(Selected.Items[i].FileName));
AWStrListReportText.Add(AWStrListReportLine.CommaText);
AWStrListReportLine.Free;
end;
// store as meteorological season if sort switch on
if cASeasonMeteoSort then
begin
AWStrSeasonMeteo := iif(cASeasonHemisphere = 'Northern',
funcGetSeasonMeteoNorth(Selected.Items[i].PhotoDate),
funcGetSeasonMeteoSouth(Selected.Items[i].PhotoDate)); // CALL FUNC
// add season label to item
if cASeasonAddLabel and (Length(AWStrSeasonMeteo) = 6) then // if switch on and valid season
procLabelImgItemKeywords(Selected.Items[i], 'meteorological ' + WideLowerCase(AWStrSeasonMeteo)); // CALL PROC
// store item to collection
Case funcChangeToTitleCase(AWStrSeasonMeteo) of // CALL FUNC
'Winter': PublicCatalog.StoreItemToCollection(Selected.Items[i], AImgCollSeasonMeteoWinter, PublicOptions.XMPSyncReadSettings, False);
'Spring': PublicCatalog.StoreItemToCollection(Selected.Items[i], AImgCollSeasonMeteoSpring, PublicOptions.XMPSyncReadSettings, False);
'Summer': PublicCatalog.StoreItemToCollection(Selected.Items[i], AImgCollSeasonMeteoSummer, PublicOptions.XMPSyncReadSettings, False);
'Autumn': PublicCatalog.StoreItemToCollection(Selected.Items[i], AImgCollSeasonMeteoAutumn, PublicOptions.XMPSyncReadSettings, False);
else
begin
AWStrWarningMeteo := 'Meteo warning: some seasons not assigned' + CrLf;
PublicCatalog.StoreItemToCollection(Selected.Items[i], AImgCollSeasonMeteonotassigned, PublicOptions.XMPSyncReadSettings, False);
end;
end;
AWStrListReportLine := TStringList.Create;
AWStrListReportLine.Add(UTF8Encode(IntToStr(i)));
AWStrListReportLine.Add(UTF8Encode('METEO'));
AWStrListReportLine.Add(UTF8Encode(funcChangeToTitleCase(AWStrSeasonMeteo))); // CALL FUNC
AWStrListReportLine.Add(UTF8Encode(DateTimeToExifDate(Selected.Items[i].PhotoDate)));
AWStrListReportLine.Add(UTF8Encode(AWStrItemName));
AWStrListReportLine.Add(UTF8Encode(Selected.Items[i].FileName));
AWStrListReportText.Add(AWStrListReportLine.CommaText);
AWStrListReportLine.Free;
end;
end;
// send feedback
SendVisualFeedback('season sort complete', 3000);
// close progress bar
if AxomProgress.Cancel then
begin
Say('AxomProgress Cancelled.');
Exit; // exit procedure
end;
AxomProgress.Hide;
AxomProgress.Free;
ATStrListImgItemAstro.Free;
ATStrListImgItemMeteo.Free;
end
// STEP 06 - PROCESS
// SELECTED ITEM IS A COLLECTION OR A PORTFOLIO
else if (ACatPropGroup.Collections.Count > 0) or (ACatPropGroup.Albums.Count > 0) then
begin
//gACatItemsArray := TidElement.Create(nil); // global var // FOR ARRAY METHOD
// get image items for all sub collections
gATStrListCatItemGUID := TTntStringList.Create; // global var
gATStrListCatItemGUID.Duplicates := dupAccept; // global var
gATStrListCatItemParentGUID := TTntStringList.Create; // global var
gATStrListCatItemParentGUID.Duplicates := dupAccept; // global var
if ACatPropGroup.Collections.Count > 0 then
begin
AWStrSelectedObject := 'Collection: ' + ACatPropGroup.Collections.Items[0].CollectionName;
procGetCollAllCatItems(ACatPropGroup.Collections.Items[0]); // CALL PROC
end
else if ACatPropGroup.Albums.Count > 0 then
begin
AWStrSelectedObject := 'Portfolio: ' + ACatPropGroup.Albums.Items[0].ModelName;
AImgColls := TImageCollections.Create(TImageCollection, '');
PublicCatalog.EnumCollectionsforParent(ACatPropGroup.Albums.Items[0].GUID, AImgColls);
procGetCollsAllCatItems(AImgColls); // CALL PROC
end;
procDeleteTStrListDupCatItem; // CALL PROC
// initialise progress bar
AxomProgress := TxomProgress.Create(nil);
AxomProgress.Caption := 'Processing ' + AWStrSelectedObject;
AxomProgress.Pos := 0;
AxomProgress.Max := gATStrListCatItemGUID.Count; // global var
AxomProgress.CanCancel := True;
AxomProgress.Show;
// sort items for all sub collections
ATStrListImgItemAstro := TTntStringList.Create;
ATStrListImgItemMeteo := TTntStringList.Create;
//for i := 0 to gACatItemsArray.Count - 1 do // global var // FOR ARRAY METHOD
for i := 0 to gATStrListCatItemGUID.Count - 1 do // global var
begin
//ACatItemElem := gACatItemsArray.Elements.Items[i]; // global var // FOR ARRAY METHOD
//PublicCatalog.EnumCollectionItem(ACatItemElem.Prop['CatItemParentGUID'], ACatItemElem.Prop['CatItemGUID'], AImgItem); // FOR ARRAY METHOD
AImgItem := TImageItem.Create(nil);
PublicCatalog.EnumCollectionItem(gATStrListCatItemParentGUID.Strings[i], gATStrListCatItemGUID.Strings[i], AImgItem); // global var
// '.ImageName' is no longer working (use '.FileName' instead)
// // some items return AImgItem.ImageName without extension:
// if ExtractFileExt(AImgItem.ImageName) = '' then
// AWStrItemName := AImgItem.ImageName + ExtractFileExt(AImgItem.FileName);
// else
// AWStrItemName := AImgItem.ImageName;
// get item name
AWStrItemName := WideExtractFileName(AImgItem.FileName);
// update progress bar
AxomProgress.Pos := i + 1;
AxomProgress.ProgressText := 'item ' + IntToStr(i) + ' of ' +
IntToStr(gATStrListCatItemGUID.Count) +
': ' + AWStrItemName; // global var
if AxomProgress.Cancel then
Break; // exit for-loop
// get item season
AWStrWarningAstro := '';
AWStrWarningMeteo := '';
// store as astronomical season if sort switch on
if cASeasonAstroSort then
begin
AWStrSeasonAstro := iif(cASeasonHemisphere = 'Northern',
funcGetSeasonAstroNorth(AImgItem.PhotoDate),
funcGetSeasonAstroSouth(AImgItem.PhotoDate)); // CALL FUNC
// add season label to item
if cASeasonAddLabel and (Length(AWStrSeasonAstro) = 6) then // if switch on and valid season
procLabelImgItemKeywords(AImgItem, 'astronomical ' + WideLowerCase(AWStrSeasonAstro)); // CALL PROC
// store item to collection
Case funcChangeToTitleCase(AWStrSeasonAstro) of // CALL FUNC
'Winter': PublicCatalog.StoreItemToCollection(AImgItem, AImgCollSeasonAstroWinter, PublicOptions.XMPSyncReadSettings, False);
'Spring': PublicCatalog.StoreItemToCollection(AImgItem, AImgCollSeasonAstroSpring, PublicOptions.XMPSyncReadSettings, False);
'Summer': PublicCatalog.StoreItemToCollection(AImgItem, AImgCollSeasonAstroSummer, PublicOptions.XMPSyncReadSettings, False);
'Autumn': PublicCatalog.StoreItemToCollection(AImgItem, AImgCollSeasonAstroAutumn, PublicOptions.XMPSyncReadSettings, False);
else
begin
AWStrWarningAstro := 'Astro warning: some seasons not assigned' + CrLf;
PublicCatalog.StoreItemToCollection(AImgItem, AImgCollSeasonAstronotassigned, PublicOptions.XMPSyncReadSettings, False);
end;
end;
AWStrListReportLine := TStringList.Create;
AWStrListReportLine.Add(UTF8Encode(IntToStr(i)));
AWStrListReportLine.Add(UTF8Encode('ASTRO'));
AWStrListReportLine.Add(UTF8Encode(funcChangeToTitleCase(AWStrSeasonAstro))); // CALL FUNC
AWStrListReportLine.Add(UTF8Encode(DateTimeToExifDate(AImgItem.PhotoDate)));
AWStrListReportLine.Add(UTF8Encode(AWStrItemName));
AWStrListReportLine.Add(UTF8Encode(AImgItem.FileName));
AWStrListReportText.Add(AWStrListReportLine.CommaText);
AWStrListReportLine.Free;
end;
// store as meteorological season if sort switch on
if cASeasonMeteoSort then
begin
AWStrSeasonMeteo := iif(cASeasonHemisphere = 'Northern',
funcGetSeasonMeteoNorth(AImgItem.PhotoDate),
funcGetSeasonMeteoSouth(AImgItem.PhotoDate)); // CALL FUNC
// add season label to item
if cASeasonAddLabel and (Length(AWStrSeasonMeteo) = 6) then // if switch on and valid season
procLabelImgItemKeywords(AImgItem, 'meteorological ' + WideLowerCase(AWStrSeasonMeteo)); // CALL PROC
// store item to collection
Case funcChangeToTitleCase(AWStrSeasonMeteo) of // CALL FUNC
'Winter': PublicCatalog.StoreItemToCollection(AImgItem, AImgCollSeasonMeteoWinter, PublicOptions.XMPSyncReadSettings, False);
'Spring': PublicCatalog.StoreItemToCollection(AImgItem, AImgCollSeasonMeteoSpring, PublicOptions.XMPSyncReadSettings, False);
'Summer': PublicCatalog.StoreItemToCollection(AImgItem, AImgCollSeasonMeteoSummer, PublicOptions.XMPSyncReadSettings, False);
'Autumn': PublicCatalog.StoreItemToCollection(AImgItem, AImgCollSeasonMeteoAutumn, PublicOptions.XMPSyncReadSettings, False);
else
begin
AWStrWarningMeteo := 'Meteo warning: some seasons not assigned' + CrLf;
PublicCatalog.StoreItemToCollection(AImgItem, AImgCollSeasonMeteonotassigned, PublicOptions.XMPSyncReadSettings, False);
end;
end;
AWStrListReportLine := TStringList.Create;
AWStrListReportLine.Add(UTF8Encode(IntToStr(i)));
AWStrListReportLine.Add(UTF8Encode('METEO'));
AWStrListReportLine.Add(UTF8Encode(funcChangeToTitleCase(AWStrSeasonMeteo))); // CALL FUNC
AWStrListReportLine.Add(UTF8Encode(DateTimeToExifDate(AImgItem.PhotoDate)));
AWStrListReportLine.Add(UTF8Encode(AWStrItemName));
AWStrListReportLine.Add(UTF8Encode(AImgItem.FileName));
AWStrListReportText.Add(AWStrListReportLine.CommaText);
AWStrListReportLine.Free;
end;
AImgItem.Free;
end;
// send feedback
SendVisualFeedback('season sort complete', 3000);
// close progress bar
if AxomProgress.Cancel then
begin
Say('AxomProgress Cancelled.');
Exit; // exit procedure
end;
AxomProgress.Hide;
AxomProgress.Free;
ATStrListImgItemAstro.Free;
ATStrListImgItemMeteo.Free;
gATStrListCatItemGUID.Free; // global var
gATStrListCatItemParentGUID.Free; // global var
if ACatPropGroup.Albums.Count > 0 then
AImgColls.Free;
end
// STEP 07 - PROCESS
// SELECTED ITEM IS NOT AN IMAGE, A COLLECTION OR A PORTFOLIO
else
begin
Say('Please select an Image, Collection or Portfolio (under Portfolios tab).');
Exit; // exit script
end;
// STEP 08 - DIALOG
// save sorted items to file
if cASaveReport then
begin
// prepare report file strings
AWStrReportPath := iif(cAScriptReportPath = '',
OMPublic.WindowsMyDocumentsDir,
cAScriptReportPath);
AWStrReportPath := AWStrReportPath + cAScriptReportDir + '\';
AWStrReportName := WideChangeFileExt(cAScriptName, '') + '_' +
WideChangeFileExt(cAScriptReportName, '') + '_' +
AWStrDateTimeSuffix + '.csv';
AWStrReportFile := AWStrReportPath + AWStrReportName;
// create report directory if it doesn't already exist
ABlnInvalidDir := False;
if not WideDirectoryExists(AWStrReportPath) then
if not WideForceDirectories(AWStrReportPath) then
ABlnInvalidDir := True;
if not ABlnInvalidDir then
AWStrListReportText.SaveToFile(AWStrReportFile);
// prepare message
AWStrMessage := 'Items saved to file:' +
sLineBreak + sLineBreak +
AWStrReportFile;
// send feedback
SendVisualFeedback(AWStrMessage, 5000);
if cAShowDialog then
begin
// prepare warning
AWStrWarning := AWStrWarningAstro + AWStrWarningMeteo;
if AWStrWarning <> '' then
AWStrWarning := AWStrWarning + 'Please see saved file for details.';
// show dialog
ABlnAskChecked := False;
ATStrListAskOptions := TTntStringList.Create;
AIntAskButton := AskCustom(
'Season Sort Complete',
AWStrWarning + CrLf2 + AWStrMessage,
'Edit script to specify editor to open report ' +
'''.csv'' file.' , // 'hidden details'
'Open report folder and file', // 'check box'
ABlnAskChecked,
ATStrListAskOptions);
ATStrListAskOptions.Free;
// open report folder and file
// if button OK clicked AIntAskButton = -99
// if button Cancel clicked AIntAskButton = -1
if AIntAskButton <> -1 then
begin
if ABlnAskChecked = True then
begin
ShellDoExecute(nil, AWStrReportPath);
if cAEditor = '' then
ShellDoExecute(nil, AWStrReportFile);
else
RunCommand(cAEditor + ' "' + AWStrReportFile + '"');
end;
end;
end;
end;
AWStrListReportText.Free;
AImgCollSeason.Free;
AImgCollSeasonDateTime.Free;
AImgCollSeasonAstro.Free;
AImgCollSeasonAstroWinter.Free;
AImgCollSeasonAstroSpring.Free;
AImgCollSeasonAstroSummer.Free;
AImgCollSeasonAstroAutumn.Free;
AImgCollSeasonAstronotassigned.Free;
AImgCollSeasonMeteo.Free;
AImgCollSeasonMeteoWinter.Free;
AImgCollSeasonMeteoSpring.Free;
AImgCollSeasonMeteoSummer.Free;
AImgCollSeasonMeteoAutumn.Free;
AImgCollSeasonMeteonotassigned.Free;
end;
|