web-dev-qa-db-fra.com

Sql Server conversion de chaîne en date

Je veux convertir une chaîne comme ceci:

'10/15/2008 10:06:32 PM'

dans la valeur DATETIME équivalente dans Sql Server.

Dans Oracle, je dirais ceci:

TO_DATE('10/15/2008 10:06:32 PM','MM/DD/YYYY HH:MI:SS AM')

Cette question implique que je dois analyser la chaîne dans l'un des formats standard , puis convertir à l'aide de l'un de ces codes. Cela semble ridicule pour une opération aussi banale. Y a-t-il un moyen plus facile?

165
JosephStyons

SQL Server (2005, 2000, 7.0) ne dispose d'aucun moyen flexible, ni même flexible, de prendre une date-heure structurée de manière arbitraire au format chaîne et de la convertir en type de données datetime.

Par "arbitrairement", j'entends "une forme que la personne qui l'a écrite, bien que peut-être pas vous ni moi, ni quelqu'un de l'autre côté de la planète, considérons qu'elle est intuitive et tout à fait évidente". Franchement, je ne suis pas sûr qu'il existe un tel algorithme.

32
Philip Kelley

Essaye ça

Cast('7/7/2011' as datetime)

et

Convert(varchar(30),'7/7/2011',102)

Voir CAST et CONVERT (Transact-SQL) pour plus de détails.

271
gauravg

Exécutez ceci via votre processeur de requête. Il formate les dates et/ou les heures de cette manière et l’un d’eux devrait vous donner ce que vous cherchez. Ce ne sera pas difficile de s'adapter:

Declare @d datetime
select @d = getdate()

select @d as OriginalDate,
convert(varchar,@d,100) as ConvertedDate,
100 as FormatValue,
'mon dd yyyy hh:miAM (or PM)' as OutputFormat
union all
select @d,convert(varchar,@d,101),101,'mm/dd/yy'
union all
select @d,convert(varchar,@d,102),102,'yy.mm.dd'
union all
select @d,convert(varchar,@d,103),103,'dd/mm/yy'
union all
select @d,convert(varchar,@d,104),104,'dd.mm.yy'
union all
select @d,convert(varchar,@d,105),105,'dd-mm-yy'
union all
select @d,convert(varchar,@d,106),106,'dd mon yy'
union all
select @d,convert(varchar,@d,107),107,'Mon dd, yy'
union all
select @d,convert(varchar,@d,108),108,'hh:mm:ss'
union all
select @d,convert(varchar,@d,109),109,'mon dd yyyy hh:mi:ss:mmmAM (or PM)'
union all
select @d,convert(varchar,@d,110),110,'mm-dd-yy'
union all
select @d,convert(varchar,@d,111),111,'yy/mm/dd'
union all
select @d,convert(varchar,@d,12),12,'yymmdd'
union all
select @d,convert(varchar,@d,112),112,'yyyymmdd'
union all
select @d,convert(varchar,@d,113),113,'dd mon yyyy hh:mm:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,114),114,'hh:mi:ss:mmm(24h)'
union all
select @d,convert(varchar,@d,120),120,'yyyy-mm-dd hh:mi:ss(24h)'
union all
select @d,convert(varchar,@d,121),121,'yyyy-mm-dd hh:mi:ss.mmm(24h)'
union all
select @d,convert(varchar,@d,126),126,'yyyy-mm-dd Thh:mm:ss:mmm(no spaces)'
47
Taptronic

Dans SQL Server Denali, vous serez en mesure de faire quelque chose qui correspond à ce que vous recherchez. Mais vous ne pouvez toujours pas transmettre une chaîne de date délirante définie arbitrairement et vous attendre à ce que SQL Server soit adapté. Voici un exemple utilisant quelque chose que vous avez posté dans votre propre réponse. La fonction FORMAT () peut également accepter les paramètres régionaux en tant qu'argument facultatif. Elle est basée sur le format .Net. La plupart des formats de jetons que vous vous attendez à trouver seront donc présents.

DECLARE @d DATETIME = '2008-10-13 18:45:19';

-- returns Oct-13/2008 18:45:19:
SELECT FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss');

-- returns NULL if the conversion fails:
SELECT TRY_PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);

-- returns an error if the conversion fails:
SELECT PARSE(FORMAT(@d, N'MMM-dd/yyyy HH:mm:ss') AS DATETIME);

Je vous encourage fortement à prendre plus de contrôle et à assainir vos entrées de date. Les jours où il était temps de laisser les gens saisir les dates en utilisant le format de leur choix dans un champ de texte libre devraient être bien en retard sur nous maintenant. Si quelqu'un entre le 8/9/2011, est-ce le 9 août ou le 8 septembre? Si vous leur faites choisir une date sur un contrôle de calendrier, l'application peut contrôler le format. Peu importe combien vous essayez de prédire le comportement de vos utilisateurs, ils trouveront toujours un moyen plus bête d'entrer une date que vous n'aviez pas planifiée.

Jusqu'à Denali, cependant, je pense que @Ovidiu a le meilleur conseil à ce jour ... cela peut être rendu assez trivial en implémentant votre propre fonction CLR. Ensuite, vous pouvez écrire un cas/un commutateur pour autant de formats farfelus que vous le souhaitez.


PDATE pour @dhergert:

SELECT TRY_PARSE('10/15/2008 10:06:32 PM' AS DATETIME USING 'en-us');
SELECT TRY_PARSE('15/10/2008 10:06:32 PM' AS DATETIME USING 'en-gb');

Résultats:

2008-10-15 22:06:32.000
2008-10-15 22:06:32.000

Vous devez toujours avoir cet autre élément crucial d'information en premier. Vous ne pouvez pas utiliser T-SQL natif pour déterminer si 6/9/2012 est le 9 juin ou le 6 septembre.

42
Aaron Bertrand

Pour ce problème, la meilleure solution consiste à avoir une fonction CLR dans SQL Server 2005 qui utilise l’une des fonctions DateTime.Parse ou ParseExact pour renvoyer la valeur DateTime avec un format spécifié.

11
Ovidiu Pacurar

pourquoi ne pas essayer

select convert(date,'10/15/2011 00:00:00',104) as [MM/dd/YYYY]

les formats de date peuvent être trouvés à l'adresse Aide SQL Server> Formats de date SQL Server

9
Scott Gollaglee

Utilisez ceci:

SELECT convert(datetime, '2018-10-25 20:44:11.500', 121) -- yyyy-mm-dd hh:mm:ss.mmm

Et reportez-vous au tableau de la documentation officielle pour connaître les codes de conversion.

6
Simone

Personnellement, si vous traitez avec des formats arbitraires ou totalement hors du mur, si vous savez ce qu’ils sont à l’avance ou si vous allez le faire, utilisez simplement regexp pour extraire les sections de la date de votre choix et former un composant date/date/heure valide.

3
SyWill

Cette page contient des références pour toutes les conversions datetime spécifiées disponibles pour la fonction CONVERT. Si vos valeurs ne correspondent pas à l’un des schémas acceptables, alors je pense que la meilleure chose à faire est d’emprunter la voie ParseExact.

3
tvanfosson

Si vous voulez que SQL Server essaie de le comprendre, utilisez simplement CAST CAST ("quel que soit" la date/heure AS). Cependant, c'est une mauvaise idée en général. Il y a des problèmes avec les dates internationales qui pourraient se présenter. Ainsi, comme vous l'avez constaté, pour éviter ces problèmes, vous souhaitez utiliser le format canonique ODBC de la date. C'est le format numéro 120, 20 est le format pour seulement deux années numériques. Je ne pense pas que SQL Server possède une fonction intégrée qui vous permet de fournir un format donné à un utilisateur. Vous pouvez écrire le vôtre et même en trouver un si vous effectuez une recherche en ligne.

0
Will Rickards