user1307: I read the full api method list and did not seem to find one.
I suppose there is no command specifically for that purpose, so what is the general way of doing this?
I would consider checking the time stamp of the last generated block, but the getblock method is not really explained in much detail.
EDIT:
Some people answer that I should compare the block count with one of an online block chain monitor. That is not really a practical solution. The Bitcoin-Qt client has a way of knowing when syncing is done (the V-sign vs the syncing icon), so why doesn't bitcoind? How does the Bitcoin-Qt get this information?

user22924: There are some neat solutions here, and maybe this is just overly simple but, if you're legitimately catching up to the blockchain and not basically at the end so only getting that new block once every ~ 10 minutes, look at your cpu usage.
If you're on linux, run "top".  bitcoind will be working its butt off calculating every hash of every block through the blockchain.  Once it's caught up, it's basically idle.

user18794: Update August 7 2015 ~ start
So after having an IP or two banned because of checking to often... so, I'll provide some options on how to avoid getting banned.
First don't use the script under this update; the variable expansion Bash preforms causes multiple calls to https://blockchain.info in to short of a time frame. You can try adding sleep 120 between the assignment and calls but that would be very slow.
Second the key things are; Checking local count $(bitcoin-cli getblockcount) and Checking a well known node $(wget -q -O - http://blockchain.info/q/getblockcount) and Checking local sync state $(bitcoin-cli getblocktemplate)
To combine the Blockchain from your node to another in one line
$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))
# To print this with echo and date stamp
echo "    $(date) : $($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))"
# To redirect and exit with 0 : ie place in crontab
echo "$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))" > /var/log/btc_blocks_left_to_sync.log 2>&1

The last one above is likely the best for scripting as the file it saves to can be read for just the number inside or the last time it was modifide.
Update August 7 2015 ~ end
Indeed the correct function call is shown there, @BinaryMage, thank you.

possible duplicate of When downloading the blockchain for the first time, how do I know when it's done? –  BinaryMage Apr 4 '13 at 0:50

The person to show the correct function was @LoHoris, however, the updates to Bitcoin node software now uses bitcoin-cli getblocktemplate and not bitcoind for these lookups.
Thanks to both of them it is possible to offer you all a combination of both answers wrapped into a checker script; ready for your customization and updated for the year 2015

    #!/bin/bash
    timed_wait=600
    vars_to_load(){
        ## Set vars to function such that they are set upon every call
        localCheck=$(bitcoin-cli getblockcount)
        crossCheck=$(wget -q -O - http://blockchain.info/q/getblockcount)
        diffBlocks=$(($crossCheck-$localCheck))
        localSize=$(ls -hal ~/.bitcoin/blocks | awk '/total/{print $2}')
    }
    check_sync(){
        while true
        do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
            sleep $timed_wait
        done
    }
    networked_sync(){
        vars_to_load
        ## Function to print difference in node sync
        if [ $diffBlocks -eq 0 ]
        then
            echo "Sync is good with $diffBlocks blocks off"
        else
            echo "Sync has $diffBlocks blocks left to download"
        fi
    }
    check_sync


This script first checks the exit status of bitcoin-cli getblocktemplate because anything other than 0 is usually an error it'll run the other parts only if bitcoin-cli getblocktemplate shows an error. Of course it is possible to check for specific error codes instead and do things for specific error codes... but this works fine as a template for me when setting up BTC nodes in a headless environment.
The other checks then compare local block count verses https://blockchain.info and prints out how many blocks your system is off. These only run when local check of sync status error out thus if you're on a slower like @Steven Roose mentioned then this script is ideal.
By default the wait time between checks is 600 seconds (10 minuets) to keep network checks and local checks to a minimum, however, for logging and better resource management it is easy enough to comment out the while, do, and done and sleep $timed_wait lines. And add one line to crontab to accomplish running on a schedule. Last modify the very end of the script to write output to a file.

The function modified;
    check_sync(){
    #   while true
    #   do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
    #       sleep $timed_wait
    #   done
    }


And to run every 10 minuets
    sudo nano /etc/crontab
        */10 *  * * *   root    /pathTo/script.sh 2>&1

Then to enable logging modify the call that starts every thing within the script;
    check_sync | tee -a /tmp/BTCsync_log.txt

Hopefully this is acceptable enough of an answer to mark this question as [Solved] such that future  web searchers can have an easier time of this. 

user33861: Not seeing any trivial answers here. Here's what i did.
Use API CALL "getblockchaininfo"
Parameter "verificationprogress" will be ~= 1.0, if you are synced.
Warning: this appears to be based on time, your clock will need to be somewhat accurate.
I check that it is >= 0.999 to determine if i'm in sync.

user35098: A bit hacky, but the debug log shows your "progress" as far as bitcoind is concerned.
tail -n 1 ~/.bitcoin/debug.log

Gives you something like 
2016-04-26 19:02:21 UpdateTip: new best=000000000000000002a9b8f81c231c99b86f79fae383fb1fc046974f7fdcf118  height=405098  log2_work=84.399379  tx=119389857  date=2016-03-31 10:06:53 
progress=0.982752  cache=0.5MiB(0tx)

In this case, I'm 98 percent "done".

user13239: Considering that you are always somewhat out of sync, here is how you can get by how long in seconds, and then you can divide by 60 or 3600 to get it in minutes or hours.
If you want to do it manually:
# bitcoin-cli getblockcount
2345
# bitcoin-cli getblockhash 2345
000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062
# bitcoin-cli getblock 000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062 | grep "time"
    "time" : 1233313208,
# echo $((`date +%s`-1233313208))
<number of seconds>

Or the same in two steps
bitcoin-cli getblock `bitcoin-cli getblockhash \`bitcoin-cli getblockcount\`` | grep time
    "time" : 1233313208,
echo $((`date +%s`-1233313208))
<number of seconds>

I didn't find a way to do it in one call, so here is a script that does the whole thing, with no error checking as you can see:
#!/bin/bash
cnt=`bitcoin-cli getblockcount`
hash=`bitcoin-cli getblockhash ${cnt}`
timeline=`bitcoin-cli getblock $hash | grep '"time"'`
ltrimtime=${timeline#*time\" : }
newest=${ltrimtime%%,*}
echo $((`date +%s`-$newest))

Then you can replace
echo $((`date +%s`-$newest))

To get the number of minutes like this:
echo $(((`date +%s`-$newest)/60))

Or the number of hours like that:
echo $(((`date +%s`-$newest)/3600))

Or, assuming you have perl (which you probably have) and that you prefer to have the date of the last block:
perl -le "print scalar localtime $newest;"


user30706: Bitcoind no longer supports RPC calls. Try:
watch bitcoin-cli getblockchaininfo
When the displayed number of blocks equals the displayed number of headers, you're synced!

user208: There is no way for checking whether syncing is done, simply because it isn't known.
Slightly abstractly, and probably not useful in your case, the client is always syncing: there is no real difference between "having all blocks" and "not having all blocks" - it always has all blocks that it knows about, and doesn't know whether there are blocks which it misses.
What the GUI shows you is a guess. It checks the age of the last known block, and if it is (IIRC) more than 90 minutes ago, it assumes it's out of sync. This is usually a good indicator, but it will rarely yet certainly randomly fail from time to time.
The core code has another heuristic built-in, which uses block heights reported by other nodes (without verifying that information in any way, so it's easily cheated). This information is used to determine whether it should optimize cache behaviour for many fast operations, or reliability. It's not exposed directly either, but the getwork() and getblocktemplate() RPCs will fail in this mode.

user4356: I use a python script that grabs http://blockchain.info/q/getblockcount and compares it to the output of bitcoind getblockcount.
As others have said, there is no absolute way of telling if your blockchain is up to date.
Anyway, here is my script:
    import httplib2
    from bitcoinrpc.authproxy import AuthServiceProxy
    access = AuthServiceProxy('#########')
    try:
            blockCount = access.getblockcount()
    except Exception as e:
            print "Problems connecting to bitcoin wallet:"
    else:
            try:
                    response, trueBlockCount = httplib2.Http().request("http://blockexplorer.com/q/getblockcount/")
            except Exception as e:
                    print "Unable to get true blockcount from blockexplorer:"+str(e)
            else:
                    if (int(trueBlockCount) - 5) > blockCount :
                            print "blockchain not up to date: true block count is: "+str(trueBlockCount)+", while bitcoind is at: "+str(blockCount)


1307: <p>I read the <a href="https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_calls_list">full api method list</a> and did not seem to find one.</p>

<p>I suppose there is no command specifically for that purpose, so what is the general way of doing this?</p>

<p>I would consider checking the time stamp of the last generated block, but the <code>getblock</code> method is not really explained in much detail.</p>

<p><strong>EDIT:</strong></p>

<p>Some people answer that I should compare the block count with one of an online block chain monitor. That is not really a practical solution. <em>The Bitcoin-Qt client has a way of knowing when syncing is done (the V-sign vs the syncing icon), so why doesn't bitcoind?</em> <strong>How does the Bitcoin-Qt get this information?</strong></p>
 22924: <p>There are some neat solutions here, and maybe this is just overly simple but, if you're legitimately catching up to the blockchain and not basically at the end so only getting that new block once every ~ 10 minutes, look at your cpu usage.</p>

<p>If you're on linux, run "top".  bitcoind will be working its butt off calculating every hash of every block through the blockchain.  Once it's caught up, it's basically idle.</p>
 18794: <p><strong>Update</strong> August 7 2015 ~ start</p>

<p>So after having an IP or two banned because of checking to often... so, I'll provide some options on how to avoid getting banned.
First don't use the script under this update; the variable expansion Bash preforms causes multiple calls to <a href="https://blockchain.info" rel="nofollow">https://blockchain.info</a> in to short of a time frame. You can try adding <code>sleep 120</code> between the assignment and calls but that would be very slow.
Second the key things are; Checking local count <code>$(bitcoin-cli getblockcount)</code> and Checking a well known node <code>$(wget -q -O - http://blockchain.info/q/getblockcount)</code> and Checking local sync state <code>$(bitcoin-cli getblocktemplate)</code></p>

<p>To combine the Blockchain from your node to another in one line</p>

<pre><code>$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))
# To print this with echo and date stamp
echo "    $(date) : $($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))"
# To redirect and exit with 0 : ie place in crontab
echo "$($(wget -q -O - http://blockchain.info/q/getblockcount)-$(bitcoin-cli getblockcount))" &gt; /var/log/btc_blocks_left_to_sync.log 2&gt;&amp;1
</code></pre>

<p>The last one above is likely the best for scripting as the file it saves to can be read for just the number inside or the last time it was modifide.</p>

<p><strong>Update</strong> August 7 2015 ~ end</p>

<p>Indeed the correct function call is shown there, @BinaryMage, thank you.</p>

<blockquote>
  <p>possible duplicate of When downloading the blockchain for the first time, how do I know when it's done? –  BinaryMage Apr 4 '13 at 0:50</p>
</blockquote>

<p>The person to show the correct function was @LoHoris, however, the updates to Bitcoin node software now uses <code>bitcoin-cli getblocktemplate</code> and not <code>bitcoind</code> for these lookups.</p>

<p>Thanks to both of them it is possible to offer you all a combination of both answers wrapped into a checker script; ready for your customization and updated for the year 2015</p>

<hr>

<pre><code>    #!/bin/bash
    timed_wait=600
    vars_to_load(){
        ## Set vars to function such that they are set upon every call
        localCheck=$(bitcoin-cli getblockcount)
        crossCheck=$(wget -q -O - http://blockchain.info/q/getblockcount)
        diffBlocks=$(($crossCheck-$localCheck))
        localSize=$(ls -hal ~/.bitcoin/blocks | awk '/total/{print $2}')
    }
    check_sync(){
        while true
        do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
            sleep $timed_wait
        done
    }
    networked_sync(){
        vars_to_load
        ## Function to print difference in node sync
        if [ $diffBlocks -eq 0 ]
        then
            echo "Sync is good with $diffBlocks blocks off"
        else
            echo "Sync has $diffBlocks blocks left to download"
        fi
    }
    check_sync
</code></pre>

<hr>

<p>This script first checks the exit status of <code>bitcoin-cli getblocktemplate</code> because anything other than <code>0</code> is usually an error it'll run the other parts only if <code>bitcoin-cli getblocktemplate</code> shows an error. Of course it is possible to check for specific error codes instead and do things for specific error codes... but this works fine as a template for me when setting up BTC nodes in a headless environment.
The other checks then compare local block count verses <a href="https://blockchain.info" rel="nofollow">https://blockchain.info</a> and prints out how many blocks your system is off. These only run when local check of sync status error out thus if you're on a slower like @Steven Roose mentioned then this script is ideal.</p>

<p>By default the wait time between checks is <code>600</code> seconds (10 minuets) to keep network checks and local checks to a minimum, however, for logging and better resource management it is easy enough to comment out the <code>while</code>, <code>do</code>, and <code>done</code> and <code>sleep $timed_wait</code> lines. And add one line to crontab to accomplish running on a schedule. Last modify the very end of the script to write output to a file.</p>

<hr>

<p>The function modified;</p>

<pre><code>    check_sync(){
    #   while true
    #   do
            current_time=$(date)
            echo $current_time
            bitcoin-cli getblocktemplate
            if [ $? = 0 ]
            then
                echo "All synced up"
            else
                echo "Uh oh, running available checks"
                ## call function that runs it all on a timer
                networked_sync
                echo "Node has $localCheck of $crossCheck blocks available."
                echo "Size of local blockchain is $localSize"
            fi
            echo "Sleeping for $timed_wait seconds or $(($timed_wait/60)) minuets."
    #       sleep $timed_wait
    #   done
    }
</code></pre>

<hr>

<p>And to run every 10 minuets</p>

<pre><code>    sudo nano /etc/crontab
        */10 *  * * *   root    /pathTo/script.sh 2&gt;&amp;1
</code></pre>

<p>Then to enable logging modify the call that starts every thing within the script;</p>

<pre><code>    check_sync | tee -a /tmp/BTCsync_log.txt
</code></pre>

<p>Hopefully this is acceptable enough of an answer to mark this question as [Solved] such that future  web searchers can have an easier time of this. </p>
 33861: <p>Not seeing any trivial answers here. Here's what i did.</p>

<p>Use API CALL "getblockchaininfo"
Parameter "verificationprogress" will be ~= 1.0, if you are synced.</p>

<p>Warning: this appears to be based on time, your clock will need to be somewhat accurate.</p>

<p>I check that it is >= 0.999 to determine if i'm in sync.</p>
 35098: <p>A bit hacky, but the debug log shows your "progress" as far as bitcoind is concerned.</p>

<pre><code>tail -n 1 ~/.bitcoin/debug.log
</code></pre>

<p>Gives you something like </p>

<pre><code>2016-04-26 19:02:21 UpdateTip: new best=000000000000000002a9b8f81c231c99b86f79fae383fb1fc046974f7fdcf118  height=405098  log2_work=84.399379  tx=119389857  date=2016-03-31 10:06:53 
progress=0.982752  cache=0.5MiB(0tx)
</code></pre>

<p>In this case, I'm 98 percent "done".</p>
 13239: <p>Considering that you are always somewhat out of sync, here is how you can get by how long in seconds, and then you can divide by 60 or 3600 to get it in minutes or hours.</p>

<p>If you want to do it manually:</p>

<pre><code># bitcoin-cli getblockcount
2345
# bitcoin-cli getblockhash 2345
000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062
# bitcoin-cli getblock 000000007024f233aa44bc7784a78926fb1c325f9985c936ae57b94530505062 | grep "time"
    "time" : 1233313208,
# echo $((`date +%s`-1233313208))
&lt;number of seconds&gt;
</code></pre>

<p>Or the same in two steps</p>

<pre><code>bitcoin-cli getblock `bitcoin-cli getblockhash \`bitcoin-cli getblockcount\`` | grep time
    "time" : 1233313208,
echo $((`date +%s`-1233313208))
&lt;number of seconds&gt;
</code></pre>

<p>I didn't find a way to do it in one call, so here is a script that does the whole thing, with no error checking as you can see:</p>

<pre><code>#!/bin/bash
cnt=`bitcoin-cli getblockcount`
hash=`bitcoin-cli getblockhash ${cnt}`
timeline=`bitcoin-cli getblock $hash | grep '"time"'`
ltrimtime=${timeline#*time\" : }
newest=${ltrimtime%%,*}
echo $((`date +%s`-$newest))
</code></pre>

<p>Then you can replace</p>

<pre><code>echo $((`date +%s`-$newest))
</code></pre>

<p>To get the number of minutes like this:</p>

<pre><code>echo $(((`date +%s`-$newest)/60))
</code></pre>

<p>Or the number of hours like that:</p>

<pre><code>echo $(((`date +%s`-$newest)/3600))
</code></pre>

<p>Or, assuming you have perl (which you probably have) and that you prefer to have the date of the last block:</p>

<pre><code>perl -le "print scalar localtime $newest;"
</code></pre>
 30706: <p>Bitcoind no longer supports RPC calls. Try:</p>

<p><code>watch bitcoin-cli getblockchaininfo</code></p>

<p>When the displayed number of blocks equals the displayed number of headers, you're synced!</p>
 208: <p>There is no way for checking whether syncing is done, simply because it isn't <em>known</em>.</p>

<p>Slightly abstractly, and probably not useful in your case, the client is <em>always</em> syncing: there is no real difference between "having all blocks" and "not having all blocks" - it always has all blocks that it knows about, and doesn't know whether there are blocks which it misses.</p>

<p>What the GUI shows you is a guess. It checks the age of the last known block, and if it is (IIRC) more than 90 minutes ago, it assumes it's out of sync. This is usually a good indicator, but it will rarely yet certainly randomly fail from time to time.</p>

<p>The core code has another heuristic built-in, which uses block heights reported by other nodes (without verifying that information in any way, so it's easily cheated). This information is used to determine whether it should optimize cache behaviour for many fast operations, or reliability. It's not exposed directly either, but the getwork() and getblocktemplate() RPCs will fail in this mode.</p>
 4356: <p>I use a python script that grabs <a href="http://blockchain.info/q/getblockcount">http://blockchain.info/q/getblockcount</a> and compares it to the output of <code>bitcoind getblockcount</code>.</p>

<p>As others have said, there is no absolute way of telling if your blockchain is up to date.</p>

<p>Anyway, here is my script:</p>

<pre><code>    import httplib2
    from bitcoinrpc.authproxy import AuthServiceProxy
    access = AuthServiceProxy('#########')
    try:
            blockCount = access.getblockcount()
    except Exception as e:
            print "Problems connecting to bitcoin wallet:"
    else:
            try:
                    response, trueBlockCount = httplib2.Http().request("http://blockexplorer.com/q/getblockcount/")
            except Exception as e:
                    print "Unable to get true blockcount from blockexplorer:"+str(e)
            else:
                    if (int(trueBlockCount) - 5) &gt; blockCount :
                            print "blockchain not up to date: true block count is: "+str(trueBlockCount)+", while bitcoind is at: "+str(blockCount)
</code></pre>
