Y a-t-il un moyen à Delphi 5 pour convertir une chaîne en tdateTime où vous pouvez spécifier le format réel à utiliser?
Je travaille sur un jobprocessor, qui accepte les tâches de divers postes de travail. Les tâches ont une gamme de paramètres, dont certaines sont des dates, mais (malheureusement et hors de mon contrôle) sont passées en tant que chaînes. Étant donné que les travaux peuvent provenir de postes de travail différents, le format DateTime réel utilisé pour formater les dates comme une chaîne peut (et, bien sûr, réelle do ) .
Googling autour, les seules solutions rapides que j'ai trouvées étaient de changer sournoisement la variable ShortDateFormat
et la restauré à sa valeur d'origine par la suite. Étant donné que ShortDateFormat
est une variable globale et je travaille dans un environnement fileté la seule façon de fonctionner est de synchroniser tous les accès, ce qui est totalement inacceptable (et indûble).
Je pourrais copier le code de la bibliothèque de l'unité SysUtils
dans mes propres méthodes et les modifier pour travailler avec un format spécifié au lieu des variables globales, mais je me demande simplement s'il y a quelque chose de plus adéquat que je manqué.
Cordialement, et merci d'avance,
Willem
MISE À JOUR
Pour la mettre plus succinctement:
J'ai besoin de quelque chose comme StrToDate
(ou StrToDateTime
), avec l'option ajoutée de la spécification du format exact nécessaire pour convertir la chaîne en tdateTime.
J'ai créé une telle routine pour l'unité de création de crétins de Freecal, et il convient de passer à autre chose, si le portage est nécessaire du tout.
Code:
(Le code est la dernière procédure (énorme) à la fin du fichier)
documentation:
http://www.freeScal.org/docs-html/rtl/datetutils/scandateTetime.html
Notez qu'il n'est pas une inverse complète du formatDateTime, et il a quelques extensions:
Un inverse de FormatDateTetime n'est pas 100% inverse, simplement parce que l'on peut mettre par ex. jetons de temps deux fois dans la chaîne de format et ScandateTime ne saurait pas le temps à choisir.
Les chaînes comme Hn ne peuvent pas être inversées en toute sécurité. Par exemple. 1: 2 (2 minutes après 1) fournit 12 qui est analysé à 12h00, puis manque des caractères pour la partie "n".
Extensions
(Je crois que ces commentaires sont légèrement dépassés dans le sens du chapeau, certains appui asiatiques ont été ajoutés plus tard, mais je ne suis pas sûr)
Utilisez VartodateTetime à la place. Il prend en charge de nombreux formats de date dans la chaîne et les convertit automatiquement.
var
DateVal: TDateTime;
begin
DateVal := VarToDateTime('23 Sep 2010');
ShowMessage(DateToStr(DateVal));
end;
Je vois que vous utilisez Delphi 5. Certaines versions de Delphi devront ajouter des variantes à la clause utilisée; La plupart des versions ultérieures l'ajoutent pour vous. Je ne me souviens pas de quelle catégorie Delphi 5 est tombée dans.
Les versions ultérieures de Delphi peuvent prendre un argument supplémentaire en Tformates sur les fonctions de conversion de chaîne. Les tformates sont une structure contenant les différentes variables mondiales de format (ShortDateDateFormat, LongdateFormat, etc.). Donc, vous pouvez remplacer cette valeur d'une manière thread-sûre et même pour un seul appel.
Je ne me souviens pas de la version de Delphi qui a été introduite, mais je suis sûr que c'était après Delphi 5.
Alors oui, autant que je sache, vous devez soit synchroniser tous les accès à ShortDateFormat, soit utiliser une fonction différente.
Si vous voulez savoir comment cela a été résolu dans la suite de Delphi, vous pouvez jeter un coup d'œil à la source d'un peu plus moderne (ressemble à Delphi 6) sysutils.pas ici:
http://anygen.googlecome.com/.../sysutils.pas
Découvrez les versions surchargées de StrToDateTime
qui prennent un paramètre TFormatSettings
.
function StrToDateTime(const S: string;
const FormatSettings: TFormatSettings): TDateTime; overload;
Utilisez la bibliothèque REGEXPR ( https://github.com/Masterandrey/tregexpr )
var
RE: TRegExpr;
begin
RE := TRegExpr.Create;
try
RE.Expression := '^(\d\d\d\d)/(\d\d)/(\d\d)T(\d\d):(\d\d):(\d\d)$';
if RE.Exec( Value ) then
begin
try
Result := EncodeDate( StrToInt( RE.Match[1] ),
StrToInt( RE.Match[2] ),
StrToInt( RE.Match[3] ) ) +
EncodeTime( StrToInt( RE.Match[4] ),
StrToInt( RE.Match[5] ),
StrToInt( RE.Match[6] ),
0 )
except
raise EConvertError.Create( 'Invalid date-time: ' + Value )
end
end
else
raise EConvertError.Create( 'Bad format: ' + Value )
finally
RE.Free
end
end;
Je ne suis pas sûr de ce que vous voulez. Je n'utilise plus Delphi 5 mais je suis à peu près sûr que la fonction strtodateTetime existe. En utilisant, vous pouvez convertir une chaîne en TdateTime avec des paramètres de format. Ensuite, vous pouvez convertir une telle tdateTime en n'importe quel format à l'aide de FormatDateTime, ce qui vous permet d'utiliser n'importe quel format de date souhaité.
Je voudrais aller dans l'autre sens. Comme je le vois, vous avez environ deux options de ce que vous avez mentionné un vous-même
TDateTime
.Je me demande comment vous allez déterminer le format pour dire 04/05/2010.
program DateTimeConvert;
{$APPTYPE CONSOLE}
uses
SysUtils;
function GetPart(const part, input, format: string): string;
var
I: Integer;
begin
for I := 1 to Length(format) do
if Uppercase(format[I]) = Uppercase(part) then
Result := Result + input[I];
end;
function GetDay(const input, format: string): string;
begin
Result := GetPart('d', input, format);
if Length(Result) = 1 then Result := SysUtils.Format('0%0:s', [Result]);
end;
function GetMonth(const input, format: string): string;
begin
Result := GetPart('m', input, format);
if Length(Result) = 1 then Result := SysUtils.Format('0%0:s', [Result]);
end;
function GetYear(const input, format: string): string;
begin
Result := GetPart('y', input, format);
end;
function ConvertToMyLocalSettings(const input, format: string): string;
begin
Result := SysUtils.Format('%0:s/%1:s/%2:s', [GetDay(input, format), GetMonth(input, format), GetYear(input, format)]);
end;
begin
Writeln(ConvertToMyLocalSettings('05/04/2010', 'dd/mm/yyyy'));
Writeln(ConvertToMyLocalSettings('05-04-2010', 'dd-mm-yyyy'));
Writeln(ConvertToMyLocalSettings('5-4-2010', 'd-m-yyyy'));
Writeln(ConvertToMyLocalSettings('4-5-2010', 'm-d-yyyy'));
Writeln(ConvertToMyLocalSettings('4-05-2010', 'M-dd-yyyy'));
Writeln(ConvertToMyLocalSettings('05/04/2010', 'dd/MM/yyyy'));
Readln;
end.