SQL ServerのDateTimeデータ型から日付のみを返す方法


1778
SELECT GETDATE()

戻り値: 2008-09-22 15:24:13.790

時間の部分なしで日付の部分が欲しい: 2008-09-22 00:00:00.000

どうすれば入手できますか?


4
時刻なしで日付データ型を取得しようとしている場合、時刻が00:00:00であっても運が悪ければ、varcharを取得できますが、構造体は日付時刻であり、常にある程度の時間があります。
Quintin Robinson、

16
SQL Server 2008には、時間コンポーネントなしで日付のみを格納するための別個のDATEデータ型が含まれていることに注意してください。詳細はこちら: sql-server-performance.com/articles/dev/datetime_2008_p1.aspx
Ben Hoffstein

7
さまざまな時間削除方法のパフォーマンステスト結果を示すこの投稿をお見逃しなく。
ErikE 2012

18
投票と承認された回答で誤解を招かないようにしてください。stackoverflow.com
126984/1155650をご覧ください

8
@Rohitあなたは、2008が人々が気にする唯一のバージョンであると誤って仮定しています。(世の中にもっと多くのバージョンがあります。)投票はそれ自体が物語っています。
hktegner 2013

回答:


2487

SQL Server 2008と高い、あなたがすべきCONVERT日まで:

SELECT CONVERT(date, getdate())

古いバージョンでは、次のことができます。

SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @your_date))

例えば

SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))

くれます

2008-09-22 00:00:00.000

長所:

  • ノーvarchar< - > datetime変換が必要
  • 考える必要はありません locale

マイケルが示唆したように

このバリアントを使用します。 SELECT DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

select getdate()

SELECT DATEADD(hh, DATEDIFF(hh, 0, getdate()), 0)
SELECT DATEADD(hh, 0, DATEDIFF(hh, 0, getdate()))

SELECT DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, getdate()))

SELECT DATEADD(mm, DATEDIFF(mm, 0, getdate()), 0)
SELECT DATEADD(mm, 0, DATEDIFF(mm, 0, getdate()))

SELECT DATEADD(yy, DATEDIFF(yy, 0, getdate()), 0)
SELECT DATEADD(yy, 0, DATEDIFF(yy, 0, getdate()))

出力:

2019-04-19 08:09:35.557

2019-04-19 08:00:00.000
4763-02-17 00:00:00.000

2019-04-19 00:00:00.000
2019-04-19 00:00:00.000

2019-04-01 00:00:00.000
1903-12-03 00:00:00.000

2019-01-01 00:00:00.000
1900-04-30 00:00:00.000

52
+1これは、一般的に使用されているdouble convert()メソッド(これも何年も使用しています)より35%速いようです。良いですね。
デーン

8
私があなたの解決策に見ることができる唯一の欠点は、それが何をしているのかを知らない限り、それは少し鈍いことです。double convertメソッドを使用すると、コードのメンテナー全体にとって意図がより明確になります。ところで私はあなたに反対票を投じていません。私もあなたの方法を使い始めると思います。ありがとう@aku
ジム・バーチャル

38
@pilavdzice日時をその日の午前0時に設定しても、時間は離れません。どんな結果を期待していますか?datetimeデータ型が持っていないことができない全くの時間を。データストレージとユーザープレゼンテーションを混同していると思います。必要なのは、時間部分のない文字列(ゼロではなく空白のみ)をユーザーに表示する方法である場合は、単純に、Convert(varchar(30), @Date, 101)または同様のものが必要です。詳細については、SQL Server Books Online•キャストと変換を参照してください。
ErikE 2012

7
@ user1671639日時データ型には常に日付と時刻の両方が含まれます。一方を他方なしで適切に格納することはできません-SQL Server 2008を使用している場合を除き、この場合、「日付」と「時刻」データも分離されます。タイプ。そのようなCONVERT()を使用する場合、後で使用するために文字列が本当に必要なので、そのようにそれを行うことに行き詰まります-日付を切り捨てるのではなく日付フォーマット関数を使用した方が良いでしょう-またはCAST(... AS DATE)またはCONVERT(DATE, ...)、このページで頻繁に言及されています。
Magnus

10
任意のレベルで切り捨てるために他のキーワードと交換できるSELECT DATEADD(dd, DATEDIFF(dd, 0, @your_date), 0)ため、答えをに変更することをお勧めします。dddatepartdatetime
マイケル-クレイシャーキーはどこですか2014

717

SQLServer 2008には、「日付」データ型が含まれています。これには、時間コンポーネントのない日付のみが含まれます。SQLServer 2008以降を使用しているユーザーは、次のことができます。

SELECT CONVERT(date, GETDATE())

41
SQL2008には 'time'データ型もあり、日付と時刻を分離するという質問の残りの半分に答えます。
ミステライダン2011

8
参考までに、日付から時間を切り捨てるさまざまな方法をベンチマークしましたが、これが最速の方法でした。差は小さいものでしたが、実行回数が多い場合は明らかに高速でした。
UnhandledExcepSean 14

2
sqlserver 2005についてwt?
MAF博士、2015年

Dr.MAFが円を完了@、2008年以前の答えはここにある:stackoverflow.com/questions/113045/...
Frosty840

170

SQL 2008以降を使用している場合:

select cast(getdate() as date)

3
@FredrickGauss:どのタイプ、日付?SQL Serverのどのバージョンを使用していますか?
abatishchev

7
注意してください!@ date1 datetime = '2015-09-30 20:59:59.999'を宣言します。select cast(@ date1 as date)は '2015-10-01'を返します
Nick

6
@Nick:これはDateTimeの問題です。DateTime2代わりに使用し、それは正常に動作します。sqlfiddle.com/#!6/9eecb7/2833
abatishchev

8
@ Nick、abatishchev応答を補完する2015-10-01ために、DateTime制限により@ date1は確かにです。キャストせずに試してみてくださいDate、それがもたらし2015-10-01すぎ!declare @date1 datetime = '2015-09-30 23:59:59.999';select @date1=>2015-10-01
フレデリック2015

4
これらの覚えやすいSQLトリックの1つ。マイクが言うように、2008年以降のみですが、2005年以前のDBがどこかにあると、多くの問題が発生する可能性があります:)
NicVerAZ

73

DATEADDとDATEDIFFは、varcharに変換するよりも優れています。両方のクエリは同じ実行プランを持っていますが、実行プランは主にデータアクセス戦略に関するものであり、すべての部分の実行にかかるCPU時間に関連する暗黙のコストを必ずしも明らかにしているわけではありません。両方のクエリが数百万行のテーブルに対して実行される場合、DateDiffを使用したCPU時間は、Convert CPU時間の3分の1に近い可能性があります。

クエリの実行プランを表示するには:

set showplan_text on
GO 

DATEADDとDATEDIFFの両方がCONVERT_IMPLICITを実行します。

CONVERTソリューションはシンプルで読みやすいものもありますが、速度遅くなります。日時にキャストバックする必要はありません(これはサーバーによって暗黙的に行われます)。整数の結果も暗黙的にdatetimeに変換されるため、後でDateAddのDateDiffメソッドを実際に使用する必要はありません。


SELECT CONVERT(varchar、MyDate、101)FROM DatesTable

  |--Compute Scalar(DEFINE:([Expr1004]=CONVERT(varchar(30),[TEST].[dbo].[DatesTable].[MyDate],101)))
       |--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))

SELECT DATEADD(dd、0、DATEDIFF(dd、0、MyDate))FROM DatesTable

  |--Compute Scalar(DEFINE:([Expr1004]=dateadd(day,(0),CONVERT_IMPLICIT(datetime,datediff(day,'1900-01-01 00:00:00.000',CONVERT_IMPLICIT(datetime,[TEST].[dbo].[DatesTable].[MyDate],0)),0))))
       |--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))

@digiが示唆するようにFLOOR()を使用すると、DateDiffに近いパフォーマンスが得られますが、日時データ型を浮動小数点数にキャストして元の値が常に得られるとは限らないため、推奨されません。

みんなを覚えている:誰も信じてはいけない。パフォーマンス統計を見て、自分でテストしてください!

結果をテストするときは注意してください。クライアントに対して多くの行を選択すると、計算を実行するよりもネットワーク経由で行を送信するほうが時間がかかるため、パフォーマンスの違いが見えなくなります。そのため、すべての行の処理がサーバーによって行われることを確認してください。ただし、クライアントに送信される行セットはありません。

キャッシュの最適化がクエリに影響を与える時期について、一部の人々は混乱しているようです。同じバッチまたは別々のバッチで2つのクエリを実行しても、キャッシュには影響しません。したがって、キャッシュを手動で期限切れにするか、単純にクエリを何度か繰り返し実行することができます。クエリ#2の最適化は後続のクエリにも影響するため、必要に応じて実行#1を破棄します。

以下は、DateDiffがvarcharに変換するよりも大幅に速いことを証明する完全なテストスクリプトとパフォーマンス結果です。


リカルドC、いい調査だ!どのバージョンのSQLサーバーを使用していますか?MSSQL2000では、datediffを使用するメソッドの方が少し高速です。
aku

ちなみに私は1000.000回テストを行いました。実際のシナリオでは、パフォーマンスの違いは顕著ではないと思います
aku

このテストにはSQL Server 2005 Expressを使用しました。私は2000年に仕事をしていて、2400万行を超えるテーブルでテストして、何が得られるかを確認します。
Ricardo C

あく、同じ結果。1,000万行を超えてもパフォーマンスに違いはありません。
Ricardo C

5
同等のパフォーマンスに関する主張は正しくありません。もちろん実行計画は同じです!!! これらのパフォーマンスの測定は、実行計画を調べるのではなく、CPU使用率を比較することによって行う必要があります。
ErikE

51

これを試して:

SELECT CONVERT(VARCHAR(10),GETDATE(),111)

上記のステートメントは、現在の形式をに変換します。このリンクYYYY/MM/DD参照して、適切な形式を選択してください。


5
これは「2008/09/22」を返します
eddiegroves

1
SELECT CONVERT(VARCHAR(10)、GETDATE()、101)がmm/dd/yyyyフォーマットです。
ノミ2013

4
生のテキスト値(DBの外)に基づいて並べ替える場合は、「日本語」形式の方が良い
Simon_Weaver


21

日付形式で返却する場合

CAST(注文日AS日付)

上記のコードはSQL Server 2010で動作します

2013年12月12日のように返されます

SQL Server 2012の場合、以下のコードを使用します

CONVERT(VARCHAR(10), OrderDate , 111)

1
これは、日付だけでなく、ゼロ時間の日付を返します
ボヘミアン

1
SQLサーバーを使用している場合、どのバージョンかを知ることができますか?
Mahesh ML

1
それはMS SQL 2012年に日付と時刻の両方を返し@MaheshML
マレク

1
SQL Azureの中に作品の魅力のように
マルティン・コル

5
@MaheshML SQL Serverの2010年のようなものはありません
SvenAelterman


16

として結果が必要な場合はvarchar

SELECT CONVERT(DATE, GETDATE()) --2014-03-26
SELECT CONVERT(VARCHAR(10), GETDATE(), 111) --2014/03/26

これはすでに上で述べました。

日付と時刻の形式で結果が必要な場合は、以下のクエリのいずれかを使用する必要があります

  1. SELECT CONVERT(DATETIME, CONVERT(VARCHAR(10), GETDATE(), 111)) AS OnlyDate 

    2014-03-26 00:00:00.000

  2. SELECT CONVERT(DATETIME, CONVERT(VARCHAR(10), GETDATE(), 112)) AS OnlyDate 

    2014-03-26 00:00:00.000

  3. DECLARE  @OnlyDate DATETIME
    SET @OnlyDate = DATEDIFF(DD, 0, GETDATE())
    SELECT @OnlyDate AS OnlyDate

    2014-03-26 00:00:00.000


14
SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),103) --21/09/2011

SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),101) --09/21/2011

SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),111) --2011/09/21

SELECT CONVERT(VARCHAR,DATEADD(DAY,-1,GETDATE()),107) --Sep 21, 2011

13

FLOOR()の使用-時間の部分をカットするだけです。

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)

4
この方法は最速ではなく、日付を浮動小数点数にキャストすることは正確であることを暗黙のうちに教えていますが、そうではありません。詳細については、この投稿を参照しください。
ErikE

13

SQL Server 2012以降のバージョンを使用している場合、

Format()関数を使用します。

SQLサーバーには、すでに複数の回答とフォーマットタイプがあります。ただし、ほとんどのメソッドはややあいまいであり、特定の日付形式に関して、形式タイプまたは関数の数値を覚えておくのは困難です。これが、SQLサーバーの次のバージョンでより良いオプションがある理由です。

FORMAT ( value, format [, culture ] )

視聴者ごとに日付を指定できるので、カルチャーオプションは非常に便利です。

d(小さいパターンの場合)とD(長いパターンの場合)を覚えておく必要があります。

1. "d"-短い日付パターン。

2009-06-15T13:45:30 -> 6/15/2009 (en-US)
2009-06-15T13:45:30 -> 15/06/2009 (fr-FR)
2009-06-15T13:45:30 -> 2009/06/15 (ja-JP)

2. "D"-長い日付パターン。

2009-06-15T13:45:30 -> Monday, June 15, 2009 (en-US)
2009-06-15T13:45:30 -> 15 июня 2009 г. (ru-RU)
2009-06-15T13:45:30 -> Montag, 15. Juni 2009 (de-DE)

クエリのその他の例。

DECLARE @d DATETIME = '10/01/2011';
SELECT FORMAT ( @d, 'd', 'en-US' ) AS 'US English Result'
      ,FORMAT ( @d, 'd', 'en-gb' ) AS 'Great Britain English Result'
      ,FORMAT ( @d, 'd', 'de-de' ) AS 'German Result'
      ,FORMAT ( @d, 'd', 'zh-cn' ) AS 'Simplified Chinese (PRC) Result'; 

SELECT FORMAT ( @d, 'D', 'en-US' ) AS 'US English Result'
      ,FORMAT ( @d, 'D', 'en-gb' ) AS 'Great Britain English Result'
      ,FORMAT ( @d, 'D', 'de-de' ) AS 'German Result'
      ,FORMAT ( @d, 'D', 'zh-cn' ) AS 'Chinese (Simplified PRC) Result';

US English Result Great Britain English Result  German Result Simplified Chinese (PRC) Result
----------------  ----------------------------- ------------- -------------------------------------
10/1/2011         01/10/2011                    01.10.2011    2011/10/1

US English Result            Great Britain English Result  German Result                    Chinese (Simplified PRC) Result
---------------------------- ----------------------------- -----------------------------  ---------------------------------------
Saturday, October 01, 2011   01 October 2011               Samstag, 1. Oktober 2011        2011101

さらにフォーマットが必要な場合は、以下にアクセスできます。

  1. 標準の日付と時刻のフォーマット文字列
  2. カスタムの日付と時刻のフォーマット文字列

12

CONVERTを使用して、元の質問と同じ出力、つまりyyyy-mm-ddを取得したい場合は、CONVERT(varchar(10),[SourceDate as dateTime],121)前の2つの回答と同じコードを使用しますが、ダッシュ付きのyyyy-mm-ddに変換するコードは次のとおりです。 121。

私がsoapboxに少し乗ることができる場合、この種類のフォーマットはデータ層に属していません。そのため、実際の日付部分データ型がSQL Server 2008になるまで、オーバーヘッドの高い「トリック」がなければ、これは不可能でした。導入されました。データ層でこのような変換を行うことは、DBMSのオーバーヘッドの大きな無駄になりますが、さらに重要なのは、このようなことを2番目に行うと、基本的にはメモリ内に孤立したデータが作成され、プログラムに戻ることになります。これを別の3NF +カラムに戻したり、元に戻さずにタイプされたものと比較したりすることはできません。そのため、行ったすべてのことは、障害点の導入と関係参照の削除です。

必ず先に進んで、dateTimeデータ型を呼び出し側プログラムに返し、PRESENTATION層で必要な調整を行ってください。呼び出し元に返す前に変換を行うとすぐに、アプリケーションから参照整合性のすべての希望が取り除かれます。これにより、必要のないときにデータをhuman / code / gremlinエラーにさらす何らかの手動の復帰を行わない限り、UPDATEまたはDELETE操作が再び防止されます。


1
ただし、ユーザーが指定した日付に一致するすべてのレコードを特定の時間フィールドの日付部分として取得するクエリが必要な場合を除きます。プレゼンテーション層でのみそれを行う幸運。(変換は必要ありません。日付演算を使用できますが、アイデア
Andrew Lazarus

1
@Andrewなぜそれが問題なのですか?あなたは言うWHERE col >= @Date AND col < DATEADD(DAY, 1, @Date);-コラムから時間を取り除く理由は絶対にありません。
アーロンバートランド

1
@AaronBertrandこれは、入力の@Date時間部分がゼロである場合にのみ機能します。それが真実ではない場合でも、サーバー側で時間を切り捨てる方法を知る必要があります。書式設定はプレゼンテーションレイヤーに任せる必要があるというこの回答に同意しますが、それをフロントエンドに残しておくと切り捨ての簡単な方法を知る必要がないという意味には同意しませんでした。
Andrew Lazarus

1
@Andrewは、入力パラメーターをDATEにするだけです。私の要点は、にそのような切り捨てを適用する必要はないということですが、それはほとんどの人にとって最初の本能です。
アーロンバートランド

1
@AaronBertrand は、パラメーターのデータ型を制御できることを前提としています。ストアドプロシージャでは問題ありませんが、他の状況では不可能です。キャストして、パラメーターが必要なタイプで必要なタイプであることを確認しませんか?
Andrew Lazarus

10
SELECT DATEADD(DD, DATEDIFF(DD, 0, GETDATE()), 0)

SELECT DATEADD(DAY, 0, DATEDIFF(DAY,0, GETDATE()))

SELECT CONVERT(DATETIME, CONVERT(VARCHAR(10), GETDATE(), 101))

編集:最初の2つのメソッドは基本的に同じで、varcharメソッドへの変換を実行します。


1
これらの方法はすべて素晴らしいですが、どの方法を使用することをお勧めしますか?
エディグローブ2008

3
上の2つの「正しい」バージョンであることに注意してくださいselect dateadd(dd, datediff(dd, 0, getdate()), 0)ので、ddsは、その後のいずれかのためにスワップアウトすることが可能なキーワードあなたが選択した任意のセグメントでの日付をクリップします。(また、これは単にの略語であることに注意してください。)datepartddday
Michael-Where's Clay Shirky 2014



7

結果を列または変数に割り当てる場合は、DATEタイプを指定すると、変換は暗黙的に行われます。

DECLARE @Date DATE = GETDATE()   

SELECT @Date   --> 2017-05-03

6

これはあなたの場合にはうまくいくと思います:

CONVERT(VARCHAR(10),Person.DateOfBirth,111) AS BirthDate
//here date is obtained as 1990/09/25

6
DECLARE @yourdate DATETIME = '11/1/2014 12:25pm'    
SELECT CONVERT(DATE, @yourdate)

2
この提案は他の回答でカバーされています(複数回)。
Andriy M

6

さて、私は少し遅れていますが:)、ここに別の解決策があります。

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) as DATETIME)

結果

2008-09-22 00:00:00.000

SQL Server 2012以降を使用している場合は、次のFORMAT()ような関数を使用できます-

SELECT FORMAT(GETDATE(), 'yyyy-MM-dd')

最初の例にはまだ時間コンポーネントがあります。問題のポイントは、それをどのように削除するかでした。
ザック

5

古代のMSSQLサーバー7.0を使用していても、このコード(このリンクのおかげ)により、そのときに探していた日付形式を取得できました。

PRINT '1) Date/time in format MON DD YYYY HH:MI AM (OR PM): ' + CONVERT(CHAR(19),GETDATE())  
PRINT '2) Date/time in format MM-DD-YY: ' + CONVERT(CHAR(8),GETDATE(),10)  
PRINT '3) Date/time in format MM-DD-YYYY: ' + CONVERT(CHAR(10),GETDATE(),110) 
PRINT '4) Date/time in format DD MON YYYY: ' + CONVERT(CHAR(11),GETDATE(),106)
PRINT '5) Date/time in format DD MON YY: ' + CONVERT(CHAR(9),GETDATE(),6) 
PRINT '6) Date/time in format DD MON YYYY HH:MM:SS:MMM(24H): ' + CONVERT(CHAR(24),GETDATE(),113)

それはこの出力を生成しました:

1) Date/time in format MON DD YYYY HH:MI AM (OR PM): Feb 27 2015  1:14PM
2) Date/time in format MM-DD-YY: 02-27-15
3) Date/time in format MM-DD-YYYY: 02-27-2015
4) Date/time in format DD MON YYYY: 27 Feb 2015
5) Date/time in format DD MON YY: 27 Feb 15
6) Date/time in format DD MON YYYY HH:MM:SS:MMM(24H): 27 Feb 2015 13:14:46:630

5

日付:

SELECT CONVERT(日付、GETDATE())
SELECT CAST(GETDATE()as date)

時間:

SELECT CONVERT(時間、GETDATE()、114)
SELECT CAST(GETDATE()as time)

5

単にあなたはこのようにすることができます:

SELECT CONVERT(date, getdate())
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, @your_date))
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))

出力:

2008-09-22 00:00:00.000

または単に次のようにします:

SELECT CONVERT (DATE, GETDATE()) 'Date Part Only'

結果:

Date Part Only
--------------
2013-07-14

4

なぜDATE_FORMAT(your_datetiem_column、 '%d-%m-%Y')を使用しないのですか?

例: select DATE_FORMAT( some_datetime_column, '%d-%m-%Y' ) from table_name

'%d-%m-%Y'パーツを再配置することで、m、d、年の順序を変更できます


4

これが古いことは知っていますが、このように誰が言ったかはわかりません。私の知る限り、これはANSI標準です。

SELECT CAST(CURRENT_TIMESTAMP AS DATE)

MicrosoftがANSI標準のCURRENT_DATE変数もサポートできるとよいでしょう。


select {fn current_date()} as today私のために働く。
brianary

@brianary-それはいいことですが、ANSI SQLではありません。
点灯

それは十分に公平であり、あなたの答えはうまく移植可能ですが、T-SQLに取り組んでいる限り、これも機能します(そして、ANSI CURRENT_DATEの実装がMSにとって簡単であることを示しています)。
brianary

4

私は言及されなかった以下を支持します:

DATEFROMPARTS(DATEPART(yyyy, @mydatetime), DATEPART(mm, @mydatetime), DATEPART(dd, @mydatetime))

また、ローカルやダブルコンバージョンは関係ありません。ただし、各「日付部分」はおそらく計算を行います。したがって、datediffメソッドよりも少し遅いかもしれませんが、私にとってははるかに明確です。特に、年と月(日を1に設定)だけでグループ化する場合は特にそうです。


4

SQL SERVER 2012以降、次のことが可能です。

SELECT FORMAT(GETDATE(), 'yyyy-MM-dd 00:00:00.000')


4

SQL Server 2000の場合

CAST(
(
    STR( YEAR( GETDATE() ) ) + '/' +
    STR( MONTH( GETDATE() ) ) + '/' +
    STR( DAY( GETDATE() ) )
)
AS DATETIME)


3

日付部分と日付の書式設定には、以下を使用できます。

DATENAME =>指定された日付の指定された日付部分を表す文字列を返します

DATEADD =>このDATEPART()関数は、年、月、日、時、分など、日付/時刻の単一の部分を返すために使用されます。

DATEPART =>指定された日付の指定された日付部分を表す整数を返します。

CONVERT()=> CONVERT()関数は、あるデータ型の式を別のデータ型に変換する一般的な関数です。この CONVERT()関数を使用して、日付/時刻データをさまざまな形式で表示できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.